Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
Adam Osuchowski
Kea
Commits
b6f93473
Commit
b6f93473
authored
Feb 04, 2014
by
Tomek Mrugalski
🛰
Browse files
[3274] Client-class can now be specified in DHCPv{4,6} subnets config
parent
290530e1
Changes
4
Hide whitespace changes
Inline
Side-by-side
src/bin/dhcp4/config_parser.cc
View file @
b6f93473
...
...
@@ -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.
}
}
};
...
...
src/bin/dhcp4/tests/config_parser_unittest.cc
View file @
b6f93473
...
...
@@ -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
));
}
}
src/bin/dhcp6/config_parser.cc
View file @
b6f93473
...
...
@@ -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
);
}
...
...
src/bin/dhcp6/tests/config_parser_unittest.cc
View file @
b6f93473
...
...
@@ -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
));
}
};
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment