BIND 10 trac3274, updated. b6f93473fc3c57fa2e74f223ddd1a65cd7f6238d [3274] Client-class can now be specified in DHCPv{4, 6} subnets config
BIND 10 source code commits
bind10-changes at lists.isc.org
Tue Feb 4 11:18:09 UTC 2014
The branch, trac3274 has been updated
via b6f93473fc3c57fa2e74f223ddd1a65cd7f6238d (commit)
from 290530e1c74db41d9dbf5e3dd733699345e7df2b (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commit b6f93473fc3c57fa2e74f223ddd1a65cd7f6238d
Author: Tomek Mrugalski <tomasz at isc.org>
Date: Tue Feb 4 12:17:54 2014 +0100
[3274] Client-class can now be specified in DHCPv{4,6} subnets config
-----------------------------------------------------------------------
Summary of changes:
src/bin/dhcp4/config_parser.cc | 9 +++
src/bin/dhcp4/tests/config_parser_unittest.cc | 86 ++++++++++++++++++++++++
src/bin/dhcp6/config_parser.cc | 9 +++
src/bin/dhcp6/tests/config_parser_unittest.cc | 89 +++++++++++++++++++++++++
4 files changed, 193 insertions(+)
-----------------------------------------------------------------------
diff --git a/src/bin/dhcp4/config_parser.cc b/src/bin/dhcp4/config_parser.cc
index 81223c7..7dd19bf 100644
--- a/src/bin/dhcp4/config_parser.cc
+++ b/src/bin/dhcp4/config_parser.cc
@@ -205,6 +205,7 @@ protected:
parser = new Uint32Parser(config_id, uint32_values_);
} else if ((config_id.compare("subnet") == 0) ||
(config_id.compare("interface") == 0) ||
+ (config_id.compare("client-class") == 0) ||
(config_id.compare("next-server") == 0)) {
parser = new StringParser(config_id, string_values_);
} else if (config_id.compare("pool") == 0) {
@@ -299,6 +300,14 @@ protected:
} catch (const DhcpConfigError&) {
// Don't care. next_server is optional. We can live without it
}
+
+ // Try setting up client class (if specified)
+ try {
+ string client_class = string_values_->getParam("client-class");
+ subnet4->allowClientClass(client_class);
+ } catch (const DhcpConfigError&) {
+ // That's ok if it fails. client-class is optional.
+ }
}
};
diff --git a/src/bin/dhcp4/tests/config_parser_unittest.cc b/src/bin/dhcp4/tests/config_parser_unittest.cc
index 6df9d21..32a2c43 100644
--- a/src/bin/dhcp4/tests/config_parser_unittest.cc
+++ b/src/bin/dhcp4/tests/config_parser_unittest.cc
@@ -2853,5 +2853,91 @@ TEST_F(Dhcp4ParserTest, subnetRelayInfo) {
EXPECT_EQ("192.0.2.123", subnet->relay_.addr_.toText());
}
+// Goal of this test is to verify that multiple subnets can be configured
+// with defined client classes.
+TEST_F(Dhcp4ParserTest, classifySubnets) {
+ ConstElementPtr x;
+ string config = "{ \"interfaces\": [ \"*\" ],"
+ "\"rebind-timer\": 2000, "
+ "\"renew-timer\": 1000, "
+ "\"subnet4\": [ { "
+ " \"pool\": [ \"192.0.2.1 - 192.0.2.100\" ],"
+ " \"subnet\": \"192.0.2.0/24\", "
+ " \"client-class\": \"alpha\" "
+ " },"
+ " {"
+ " \"pool\": [ \"192.0.3.101 - 192.0.3.150\" ],"
+ " \"subnet\": \"192.0.3.0/24\", "
+ " \"client-class\": \"beta\" "
+ " },"
+ " {"
+ " \"pool\": [ \"192.0.4.101 - 192.0.4.150\" ],"
+ " \"subnet\": \"192.0.4.0/24\", "
+ " \"client-class\": \"gamma\" "
+ " },"
+ " {"
+ " \"pool\": [ \"192.0.5.101 - 192.0.5.150\" ],"
+ " \"subnet\": \"192.0.5.0/24\" "
+ " } ],"
+ "\"valid-lifetime\": 4000 }";
+
+ ElementPtr json = Element::fromJSON(config);
+
+ EXPECT_NO_THROW(x = configureDhcp4Server(*srv_, json));
+ ASSERT_TRUE(x);
+ comment_ = parseAnswer(rcode_, x);
+ ASSERT_EQ(0, rcode_);
+
+ const Subnet4Collection* subnets = CfgMgr::instance().getSubnets4();
+ ASSERT_TRUE(subnets);
+ ASSERT_EQ(4, subnets->size()); // We expect 4 subnets
+
+ // Let's check if client belonging to alpha class is supported in subnet[0]
+ // and not supported in any other subnet (except subnet[3], which allows
+ // everyone).
+ ClientClasses classes;
+ classes.insert("alpha");
+ EXPECT_TRUE (subnets->at(0)->clientSupported(classes));
+ EXPECT_FALSE(subnets->at(1)->clientSupported(classes));
+ EXPECT_FALSE(subnets->at(2)->clientSupported(classes));
+ EXPECT_TRUE (subnets->at(3)->clientSupported(classes));
+
+ // Let's check if client belonging to beta class is supported in subnet[1]
+ // and not supported in any other subnet (except subnet[3], which allows
+ // everyone).
+ classes.clear();
+ classes.insert("beta");
+ EXPECT_FALSE(subnets->at(0)->clientSupported(classes));
+ EXPECT_TRUE (subnets->at(1)->clientSupported(classes));
+ EXPECT_FALSE(subnets->at(2)->clientSupported(classes));
+ EXPECT_TRUE (subnets->at(3)->clientSupported(classes));
+
+ // Let's check if client belonging to gamma class is supported in subnet[2]
+ // and not supported in any other subnet (except subnet[3], which allows
+ // everyone).
+ classes.clear();
+ classes.insert("gamma");
+ EXPECT_FALSE(subnets->at(0)->clientSupported(classes));
+ EXPECT_FALSE(subnets->at(1)->clientSupported(classes));
+ EXPECT_TRUE (subnets->at(2)->clientSupported(classes));
+ EXPECT_TRUE (subnets->at(3)->clientSupported(classes));
+
+ // Let's check if client belonging to some other class (not mentioned in
+ // the config) is supported only in subnet[3], which allows everyone.
+ classes.clear();
+ classes.insert("delta");
+ EXPECT_FALSE(subnets->at(0)->clientSupported(classes));
+ EXPECT_FALSE(subnets->at(1)->clientSupported(classes));
+ EXPECT_FALSE(subnets->at(2)->clientSupported(classes));
+ EXPECT_TRUE (subnets->at(3)->clientSupported(classes));
+
+ // Finally, let's check class-less client. He should be allowed only in
+ // the last subnet, which does not have any class restrictions.
+ classes.clear();
+ EXPECT_FALSE(subnets->at(0)->clientSupported(classes));
+ EXPECT_FALSE(subnets->at(1)->clientSupported(classes));
+ EXPECT_FALSE(subnets->at(2)->clientSupported(classes));
+ EXPECT_TRUE (subnets->at(3)->clientSupported(classes));
+}
}
diff --git a/src/bin/dhcp6/config_parser.cc b/src/bin/dhcp6/config_parser.cc
index f56ab75..e809a67 100644
--- a/src/bin/dhcp6/config_parser.cc
+++ b/src/bin/dhcp6/config_parser.cc
@@ -410,6 +410,7 @@ protected:
parser = new Uint32Parser(config_id, uint32_values_);
} else if ((config_id.compare("subnet") == 0) ||
(config_id.compare("interface") == 0) ||
+ (config_id.compare("client-class") == 0) ||
(config_id.compare("interface-id") == 0)) {
parser = new StringParser(config_id, string_values_);
} else if (config_id.compare("pool") == 0) {
@@ -526,6 +527,14 @@ protected:
subnet6->setInterfaceId(opt);
}
+ // Try setting up client class (if specified)
+ try {
+ string client_class = string_values_->getParam("client-class");
+ subnet6->allowClientClass(client_class);
+ } catch (const DhcpConfigError&) {
+ // That's ok if it fails. client-class is optional.
+ }
+
subnet_.reset(subnet6);
}
diff --git a/src/bin/dhcp6/tests/config_parser_unittest.cc b/src/bin/dhcp6/tests/config_parser_unittest.cc
index 147a85e..181da7c 100644
--- a/src/bin/dhcp6/tests/config_parser_unittest.cc
+++ b/src/bin/dhcp6/tests/config_parser_unittest.cc
@@ -2971,4 +2971,93 @@ TEST_F(Dhcp6ParserTest, subnetRelayInfo) {
EXPECT_EQ("2001:db8:1::abcd", subnet->relay_.addr_.toText());
}
+// Goal of this test is to verify that multiple subnets can be configured
+// with defined client classes.
+TEST_F(Dhcp6ParserTest, classifySubnets) {
+ ConstElementPtr x;
+ string config = "{ \"interfaces\": [ \"*\" ],"
+ "\"preferred-lifetime\": 3000,"
+ "\"rebind-timer\": 2000, "
+ "\"renew-timer\": 1000, "
+ "\"subnet6\": [ { "
+ " \"pool\": [ \"2001:db8:1::/80\" ],"
+ " \"subnet\": \"2001:db8:1::/64\", "
+ " \"client-class\": \"alpha\" "
+ " },"
+ " {"
+ " \"pool\": [ \"2001:db8:2::/80\" ],"
+ " \"subnet\": \"2001:db8:2::/64\", "
+ " \"client-class\": \"beta\" "
+ " },"
+ " {"
+ " \"pool\": [ \"2001:db8:3::/80\" ],"
+ " \"subnet\": \"2001:db8:3::/64\", "
+ " \"client-class\": \"gamma\" "
+ " },"
+ " {"
+ " \"pool\": [ \"2001:db8:4::/80\" ],"
+ " \"subnet\": \"2001:db8:4::/64\" "
+ " } ],"
+ "\"valid-lifetime\": 4000 }";
+
+ ElementPtr json = Element::fromJSON(config);
+
+ EXPECT_NO_THROW(x = configureDhcp6Server(srv_, json));
+ ASSERT_TRUE(x);
+ comment_ = parseAnswer(rcode_, x);
+ ASSERT_EQ(0, rcode_);
+
+ const Subnet6Collection* subnets = CfgMgr::instance().getSubnets6();
+ ASSERT_TRUE(subnets);
+ ASSERT_EQ(4, subnets->size()); // We expect 4 subnets
+
+ // Let's check if client belonging to alpha class is supported in subnet[0]
+ // and not supported in any other subnet (except subnet[3], which allows
+ // everyone).
+ ClientClasses classes;
+ classes.insert("alpha");
+ EXPECT_TRUE (subnets->at(0)->clientSupported(classes));
+ EXPECT_FALSE(subnets->at(1)->clientSupported(classes));
+ EXPECT_FALSE(subnets->at(2)->clientSupported(classes));
+ EXPECT_TRUE (subnets->at(3)->clientSupported(classes));
+
+ // Let's check if client belonging to beta class is supported in subnet[1]
+ // and not supported in any other subnet (except subnet[3], which allows
+ // everyone).
+ classes.clear();
+ classes.insert("beta");
+ EXPECT_FALSE(subnets->at(0)->clientSupported(classes));
+ EXPECT_TRUE (subnets->at(1)->clientSupported(classes));
+ EXPECT_FALSE(subnets->at(2)->clientSupported(classes));
+ EXPECT_TRUE (subnets->at(3)->clientSupported(classes));
+
+ // Let's check if client belonging to gamma class is supported in subnet[2]
+ // and not supported in any other subnet (except subnet[3], which allows
+ // everyone).
+ classes.clear();
+ classes.insert("gamma");
+ EXPECT_FALSE(subnets->at(0)->clientSupported(classes));
+ EXPECT_FALSE(subnets->at(1)->clientSupported(classes));
+ EXPECT_TRUE (subnets->at(2)->clientSupported(classes));
+ EXPECT_TRUE (subnets->at(3)->clientSupported(classes));
+
+ // Let's check if client belonging to some other class (not mentioned in
+ // the config) is supported only in subnet[3], which allows everyone.
+ classes.clear();
+ classes.insert("delta");
+ EXPECT_FALSE(subnets->at(0)->clientSupported(classes));
+ EXPECT_FALSE(subnets->at(1)->clientSupported(classes));
+ EXPECT_FALSE(subnets->at(2)->clientSupported(classes));
+ EXPECT_TRUE (subnets->at(3)->clientSupported(classes));
+
+ // Finally, let's check class-less client. He should be allowed only in
+ // the last subnet, which does not have any class restrictions.
+ classes.clear();
+ EXPECT_FALSE(subnets->at(0)->clientSupported(classes));
+ EXPECT_FALSE(subnets->at(1)->clientSupported(classes));
+ EXPECT_FALSE(subnets->at(2)->clientSupported(classes));
+ EXPECT_TRUE (subnets->at(3)->clientSupported(classes));
+}
+
+
};
More information about the bind10-changes
mailing list