Commit 810c4aed authored by Marcin Siodelski's avatar Marcin Siodelski

[#628,!341] Shared network parser supports interface-id.

parent c1eabee5
......@@ -19,6 +19,7 @@
using namespace isc::asiolink;
using namespace isc::data;
using namespace isc::util;
namespace isc {
namespace dhcp {
......@@ -205,6 +206,45 @@ SharedNetwork6Parser::parse(const data::ConstElementPtr& shared_network_data) {
"preferred-lifetime"));
}
// Get interface-id option content. For now we support string
// representation only
Optional<std::string> ifaceid;
if (shared_network_data->contains("interface-id")) {
ifaceid = getString(shared_network_data, "interface-id");
}
Optional<std::string> iface;
if (shared_network_data->contains("interface")) {
iface = getString(shared_network_data, "interface");
}
// Specifying both interface for locally reachable subnets and
// interface id for relays is mutually exclusive. Need to test for
// this condition.
if (!ifaceid.unspecified() && !iface.unspecified() && !ifaceid.empty() &&
!iface.empty()) {
isc_throw(isc::dhcp::DhcpConfigError,
"parser error: interface (defined for locally reachable "
"subnets) and interface-id (defined for subnets reachable"
" via relays) cannot be defined at the same time for "
"shared network " << name << "("
<< shared_network_data->getPosition() << ")");
}
// Configure interface-id for remote interfaces, if defined
if (!ifaceid.unspecified() && !ifaceid.empty()) {
std::string ifaceid_value = ifaceid.get();
OptionBuffer tmp(ifaceid_value.begin(), ifaceid_value.end());
OptionPtr opt(new Option(Option::V6, D6O_INTERFACE_ID, tmp));
shared_network->setInterfaceId(opt);
}
// Get interface name. If it is defined, then the subnet is available
// directly over specified network interface.
if (!iface.unspecified() && !iface.empty()) {
shared_network->setIface(iface);
}
// Interface is an optional parameter
if (shared_network_data->contains("interface")) {
shared_network->setIface(getString(shared_network_data, "interface"));
......
......@@ -220,7 +220,7 @@ TEST_F(SharedNetwork4ParserTest, parse) {
SharedNetwork4Parser parser;
SharedNetwork4Ptr network;
try {
try {
network = parser.parse(config_element);
} catch (const std::exception& ex) {
std::cout << "kabook: " << ex.what() << std::endl;
......@@ -407,13 +407,19 @@ TEST_F(SharedNetwork4ParserTest, relayInfoTests) {
class SharedNetwork6ParserTest : public SharedNetworkParserTest {
public:
/// @brief Constructor.
SharedNetwork6ParserTest()
: SharedNetworkParserTest(), network_(), use_iface_id_(false) {
}
/// @brief Creates valid shared network configuration.
///
/// @return Valid shared network configuration.
virtual std::string getWorkingConfig() const {
std::string config = "{"
" \"client-class\": \"srv1\","
" \"interface\": \"eth1\","
+ std::string(use_iface_id_ ? "\"interface-id\": " : "\"interface\": ") +
"\"eth1\","
" \"name\": \"bird\","
" \"preferred-lifetime\": 211,"
" \"rapid-commit\": true,"
......@@ -479,8 +485,13 @@ public:
return (*network_);
}
private:
public:
SharedNetwork6Ptr network_;
/// Boolean flag indicating if the interface-id should be used instead
/// of interface.
bool use_iface_id_;
};
// This test verifies that shared network parser for IPv4 works properly
......@@ -550,6 +561,41 @@ TEST_F(SharedNetwork6ParserTest, parse) {
EXPECT_EQ("2001:db8:1::cafe", addresses[0].toText());
}
// This test verifies that shared network parser for IPv4 works properly
// in a positive test scenario.
TEST_F(SharedNetwork6ParserTest, parseWithInterfaceId) {
// Use the configuration with interface-id instead of interface parameter.
use_iface_id_ = true;
std::string config = getWorkingConfig();
ElementPtr config_element = Element::fromJSON(config);
// Parse configuration specified above.
SharedNetwork6Parser parser;
SharedNetwork6Ptr network;
ASSERT_NO_THROW(network = parser.parse(config_element));
ASSERT_TRUE(network);
// Check that interface-id has been parsed.
auto opt_iface_id = network->getInterfaceId();
ASSERT_TRUE(opt_iface_id);
}
// This test verifies that error is returned when trying to configure a
// shared network with both interface and interface id.
TEST_F(SharedNetwork6ParserTest, mutuallyExclusiveInterfaceId) {
// Use the configuration with interface-id instead of interface parameter.
use_iface_id_ = true;
std::string config = getWorkingConfig();
ElementPtr config_element = Element::fromJSON(config);
// Add interface which is mutually exclusive with interface-id
config_element->set("interface", Element::create("eth1"));
// Parse configuration specified above.
SharedNetwork6Parser parser;
EXPECT_THROW(parser.parse(config_element), DhcpConfigError);
}
// This test verifies that it's possible to specify client-class
// on shared-network level.
TEST_F(SharedNetwork6ParserTest, clientClass) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment