using namespace isc::asiolink;
using namespace isc::data;
+using namespace isc::util;
namespace isc {
namespace dhcp {
"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"));
SharedNetwork4Parser parser;
SharedNetwork4Ptr network;
- try {
+ try {
network = parser.parse(config_element);
} catch (const std::exception& ex) {
std::cout << "kabook: " << ex.what() << std::endl;
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,"
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
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) {