Commit b6f93473 authored by Tomek Mrugalski's avatar Tomek Mrugalski 🛰
Browse files

[3274] Client-class can now be specified in DHCPv{4,6} subnets config

parent 290530e1
......@@ -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.
}
}
};
......
......@@ -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));
}
}
......@@ -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);
}
......
......@@ -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));
}
};
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