From e648d36192fe8c92244f77b606e7ca031823f9ac Mon Sep 17 00:00:00 2001 From: Tomek Mrugalski Date: Sat, 31 Oct 2015 16:47:51 +0900 Subject: [PATCH] [4105] Implement 4o6-interface-id parameter. --- src/bin/dhcp4/json_config_parser.cc | 13 +++++ src/bin/dhcp4/tests/config_parser_unittest.cc | 47 ++++++++++++++++++- src/lib/dhcpsrv/subnet.h | 7 ++- 3 files changed, 64 insertions(+), 3 deletions(-) diff --git a/src/bin/dhcp4/json_config_parser.cc b/src/bin/dhcp4/json_config_parser.cc index 27cc682c2f..43d5bb5251 100644 --- a/src/bin/dhcp4/json_config_parser.cc +++ b/src/bin/dhcp4/json_config_parser.cc @@ -204,6 +204,8 @@ protected: parser = new StringParser(config_id, string_values_); } else if (config_id.compare("4o6-interface") == 0) { parser = new StringParser(config_id, string_values_); + } else if (config_id.compare("4o6-interface-id") == 0) { + parser = new StringParser(config_id, string_values_); } else { isc_throw(NotImplemented, "unsupported parameter: " << config_id); } @@ -342,6 +344,17 @@ protected: // Don't care. 4o6-subnet is optional. } + // Try 4o6 specific paramter: 4o6-interface-id + try { + std::string ifaceid = string_values_->getParam("4o6-interface-id"); + OptionBuffer tmp(ifaceid.begin(), ifaceid.end()); + OptionPtr opt(new Option(Option::V6, D6O_INTERFACE_ID, tmp)); + subnet4->get4o6().interface_id_ = opt; + subnet4->get4o6().enabled_ = true; + } catch (const DhcpConfigError&) { + + } + // Try setting up client class (if specified) try { string client_class = string_values_->getParam("client-class"); diff --git a/src/bin/dhcp4/tests/config_parser_unittest.cc b/src/bin/dhcp4/tests/config_parser_unittest.cc index 50633286bd..413c98ec7d 100644 --- a/src/bin/dhcp4/tests/config_parser_unittest.cc +++ b/src/bin/dhcp4/tests/config_parser_unittest.cc @@ -3909,11 +3909,12 @@ TEST_F(Dhcp4ParserTest, 4o6subnetIface) { checkResult(status, 0); // Now check if the configuration was indeed handled and we have - // expected pool configured. + // expected subnet configured... Subnet4Ptr subnet = CfgMgr::instance().getStagingCfg()-> getCfgSubnets4()->selectSubnet(IOAddress("192.0.2.200")); ASSERT_TRUE(subnet); + // ... and that subnet has 4o6 network interface specified. Cfg4o6& dhcp4o6 = subnet->get4o6(); EXPECT_TRUE(dhcp4o6.enabled_); EXPECT_EQ(IOAddress("2001:db8::543"), dhcp4o6.subnet4o6_.first); @@ -3921,4 +3922,48 @@ TEST_F(Dhcp4ParserTest, 4o6subnetIface) { EXPECT_EQ("ethX", dhcp4o6.iface4o6_); } +// Checks if the DHCPv4 is able to parse the configuration with 4o6 network +// interface-id. +TEST_F(Dhcp4ParserTest, 4o6subnetInterfaceId) { + + ConstElementPtr status; + + // Just a plain v4 config (no 4o6 parameters) + string config = "{ " + genIfaceConfig() + "," + + "\"rebind-timer\": 2000, " + "\"renew-timer\": 1000, " + "\"subnet4\": [ { " + " \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ]," + " \"subnet\": \"192.0.2.0/24\"," + " \"4o6-interface-id\": \"vlan123\" } ]," + "\"valid-lifetime\": 4000 }"; + + ElementPtr json = Element::fromJSON(config); + + EXPECT_NO_THROW(status = configureDhcp4Server(*srv_, json)); + + // check if returned status is OK + checkResult(status, 0); + + // Now check if the configuration was indeed handled and we have + // expected 4o6-interface-id configured. + Subnet4Ptr subnet = CfgMgr::instance().getStagingCfg()-> + getCfgSubnets4()->selectSubnet(IOAddress("192.0.2.200")); + ASSERT_TRUE(subnet); + + Cfg4o6& dhcp4o6 = subnet->get4o6(); + EXPECT_TRUE(dhcp4o6.enabled_); + OptionPtr ifaceid = dhcp4o6.interface_id_; + ASSERT_TRUE(ifaceid); + + vector data = ifaceid->getData(); + const char *exp_data = "vlan123"; + // Let's convert vlan123 to vector format. + // We need to skip the last \0 byte, thuse sizeof() - 1. + vector exp(exp_data, exp_data + sizeof(exp_data) - 1); + + EXPECT_TRUE(exp == data); +} + + } diff --git a/src/lib/dhcpsrv/subnet.h b/src/lib/dhcpsrv/subnet.h index caa86f4f19..f0c72ece5c 100644 --- a/src/lib/dhcpsrv/subnet.h +++ b/src/lib/dhcpsrv/subnet.h @@ -523,11 +523,14 @@ struct Cfg4o6 { /// Specifies if 4o6 is enabled on this subnet. bool enabled_; - /// Specifies the network interface used as subnet selector + /// Specifies the network interface used as v4 subnet selector. std::string iface4o6_; - /// Specifies the IPv6 subnet used for subnet selection + /// Specifies the IPv6 subnet used for v4 subnet selection. std::pair subnet4o6_; + + /// Specifies the v6 interface-id used for v4 subnet selection. + OptionPtr interface_id_; }; /// @brief A configuration holder for IPv4 subnet. -- 2.47.2