Commit eb9efffc authored by Francis Dupont's avatar Francis Dupont
Browse files

[5425a] Ported last changes and fixes

parent 5c5c3c52
......@@ -76,18 +76,19 @@
// everyone is allowed. When a class is specified, only packets belonging
// to that class are allowed for that subnet.
"subnet4": [
// This one is for VoIP devices only.
{
// This one is for VoIP devices only.
"pools": [ { "pool": "192.0.2.1 - 192.0.2.200" } ],
"subnet": "192.0.2.0/24",
"client-class": "VoIP",
"interface": "ethX"
},
// This one doesn't have any client-class specified, so everyone
// is allowed in. The normal subnet selection rules still apply,
// though. There is also a static class reservation for a client
// using MAC address 1a:1b:1c:1d:1e:1f. This client will always
// be assigned to this class.
// This one doesn't have any client-class specified, so everyone
// is allowed in. The normal subnet selection rules still apply,
// though. There is also a static class reservation for a client
// using MAC address 1a:1b:1c:1d:1e:1f. This client will always
// be assigned to this class.
{
"pools": [ { "pool": "192.0.3.1 - 192.0.3.200" } ],
"subnet": "192.0.3.0/24",
......@@ -99,25 +100,27 @@
"interface": "ethX"
},
// The following list defines a subnet with pools. For some pools
// we defined a class that is allowed in that pool. If not specified
// everyone is allowed. When a class is specified, only packets belonging
// to that class are allowed for that pool.
{
// The following list defines a subnet with pools. For some pools
// we defined a class that is allowed in that pool. If not specified
// everyone is allowed. When a class is specified, only packets belonging
// to that class are allowed for that pool.
{
"pools": [
// This one is for VoIP devices only.
{
// This one is for VoIP devices only.
"pool": "192.0.4.1 - 192.0.4.200",
"client-class": "VoIP"
},
// This one doesn't have any client-class specified, so everyone
// is allowed in.
// This one doesn't have any client-class specified,
// so everyone is allowed in.
{
"pool": "192.0.5.1 - 192.0.5.200"
} ],
"subnet": "192.0.4.0/23",
"interface": "ethY"
}
"subnet": "192.0.4.0/23",
"interface": "ethY"
}
]
},
......
......@@ -61,9 +61,10 @@
"client-class": "cable-modems",
"interface": "ethX"
},
// The following subnet contains a class reservation for a client using
// DUID 01:02:03:04:05:0A:0B:0C:0D:0E. This client will always be assigned
// to this class.
// The following subnet contains a class reservation for a client using
// DUID 01:02:03:04:05:0A:0B:0C:0D:0E. This client will always be assigned
// to this class.
{
"pools": [ { "pool": "2001:db8:2::/80" } ],
"subnet": "2001:db8:2::/64",
......@@ -74,8 +75,9 @@
} ],
"interface": "ethX"
},
// The following subnet contains a pool with a class constraint: only
// clients which belong to the class are allowed to use this pool.
// The following subnet contains a pool with a class constraint: only
// clients which belong to the class are allowed to use this pool.
{
"pools": [
{
......
......@@ -804,18 +804,18 @@ concatenation of the strings</entry></row>
<section id="classification-pools">
<title>Configuring Pools With Class Information</title>
<para>
Similar to subnets in certain cases access to certain address or
prefix pools must be restricted to only clients that belong to a
given class, using the "client-class" when defining the pool.
Similar to the subnets, it is possible to restrict access to the certain address
or prefix pools to the clients belonging to a specific class, using
the "client-class" parameter when defining the pool.
</para>
<para>
Let's assume that the server is connected to a network segment that uses
Let's assume that the server is connected to a network segment using
the 192.0.2.0/24 prefix. The Administrator of that network has decided
that addresses from range 192.0.2.10 to 192.0.2.20 are going to be
managed by the DHCP4 server. Only clients belonging to client class
Client_foo are allowed to use this pool. Such a
configuration can be achieved in the following way:
that addresses from the range of 192.0.2.10 to 192.0.2.20 are going to be
managed by the DHCP4 server. Only the clients belonging to the client class
Client_foo are allowed to use this pool. Such a configuration can be
achieved in the following way:
<screen>
"Dhcp4": {
"client-classes": [
......@@ -833,19 +833,59 @@ concatenation of the strings</entry></row>
]
},
...
],<userinput>
],
"subnet4": [
{
"subnet": "192.0.2.0/24",
<userinput>
"pools": [
{
"pool": "192.0.2.10 - 192.0.2.20",
"client-class": "Client_foo"
}
]</userinput>
},
...
],
...
}</screen>
</para>
<para>
The following example shows restricting access to an address pool.
This configuration will restrict use of the addresses 2001:db8:1::1
to 2001:db8:1::FFFF to members of the "Client_enterprise" class.
<screen>
"Dhcp6": {
"client-classes": [
{
"name": "Client_enterprise_",
"test": "substring(option[1].hex,0,6) == 0x0002AABBCCDD'",
"option-data": [
{
"name": "dns-servers",
"code": 23,
"space": "dhcp6",
"csv-format": true,
"data": "2001:db8:0::1, 2001:db8:2::1"
}
]
},
...
],</userinput>,
],
"subnet6": [
{
"subnet": "2001:db8:1::/64",
<userinput>
"pools": [
{
"pool": "2001:db8:1::-2001:db8:1::ffff",
"client-class": "Client_foo"
}
]</userinput>
},
...
],
...
}</screen>
</para>
......
......@@ -2068,16 +2068,13 @@ It is merely echoed by the server
discussion of the classification process see <xref linkend="classify"/>.
</para>
<para>
In certain cases it is useful to differentiate between different types of
clients and treat them accordingly. It is envisaged that client
classification will be used for changing the behavior of almost any part of
the DHCP message processing, including the assignment of leases from different
pools, the assignment of different options (or different values of the same
options) etc. In the current release of the software however, there are
only three mechanisms that take advantage of client classification:
subnet selection, assignment of different options, and, for cable modems, there
are specific options for use with the TFTP server address and the boot file field.
<para>In certain cases it is useful to configure the server to differentiate between
DHCP clients types and treat them accordingly. It is envisaged that client
classification will be used for modifying the behavior of almost any part of
the DHCP message processing. In the current release of Kea, there are four
mechanisms that take advantage of the client classification in DHCPv4: subnet
selection, address pool selection, DHCP options assignment, and, for cable modems,
there are specific options for use with the TFTP server address and boot file field.
</para>
<para>
......@@ -2093,12 +2090,9 @@ It is merely echoed by the server
</para>
<para>
When subnets belong to a shared network the classification applies
to subnet selection but not to pools, e.g., a pool in a subnet
limited to a particular class can still be used by clients which do not
belong to the class if the pool they are expected to use is exhausted.
So the limit access based on class information is also available
at the pool level, see <xref linkend="classification-pools"/>.
Client classification can also be used to restrict access to specific
pools within a subnet. This is useful when to segregate clients belonging
to the same subnet into different address ranges.
</para>
<para>
......
......@@ -1927,6 +1927,14 @@ should include options from the isc option space:
discussion of the classification process see <xref linkend="classify"/>.
</para>
<para>In certain cases it is useful to configure the server to differentiate between
DHCP clients types and treat them accordingly. It is envisaged that client
classification will be used for modifying the behavior of almost any part of
the DHCP message processing. In the current release of Kea, there are three
mechanisms that take advantage of the client classification in DHCPv6: subnet
selection, address pool selection and DHCP options assignment.
</para>
<para>
In certain cases it is useful to differentiate between different types
of clients and treat them accordingly. It is envisaged that client
......@@ -1951,13 +1959,9 @@ should include options from the isc option space:
</para>
<para>
When subnets belong to a shared network the classification applies
to subnet selection but not to pools, e.g., a pool in a subnet
limited to a particular class can still be used by clients which do not
belong to the class if the pool they are expected to use is exhausted.
So the limit access based on class information is also available
at the address/prefix pool level, see <xref
linkend="classification-pools"/>.
Client classification can also be used to restrict access to specific
pools within a subnet. This is useful when to segregate clients belonging
to the same subnet into different address ranges.
</para>
<para>
......
This diff is collapsed.
......@@ -176,6 +176,17 @@ public:
}
}
/// @brief Create a solicit
Pkt6Ptr createSolicit(std::string remote_addr = "fe80::abcd") {
OptionPtr clientid = generateClientId();
Pkt6Ptr query(new Pkt6(DHCPV6_SOLICIT, 1234));
query->setRemoteAddr(IOAddress(remote_addr));
query->addOption(clientid);
query->setIface("eth1");
query->addOption(generateIA(D6O_IA_NA, 123, 1500, 3000));
return (query);
}
/// @brief Interface Manager's fake configuration control.
IfaceMgrTestConfig iface_mgr_test_config_;
};
......@@ -244,22 +255,9 @@ TEST_F(ClassifyTest, matchClassification) {
ASSERT_NO_THROW(configure(config));
// Create packets with enough to select the subnet
OptionPtr clientid = generateClientId();
Pkt6Ptr query1(new Pkt6(DHCPV6_SOLICIT, 1234));
query1->setRemoteAddr(IOAddress("fe80::abcd"));
query1->addOption(clientid);
query1->setIface("eth1");
query1->addOption(generateIA(D6O_IA_NA, 123, 1500, 3000));
Pkt6Ptr query2(new Pkt6(DHCPV6_SOLICIT, 1234));
query2->setRemoteAddr(IOAddress("fe80::abcd"));
query2->addOption(clientid);
query2->setIface("eth1");
query2->addOption(generateIA(D6O_IA_NA, 234, 1500, 3000));
Pkt6Ptr query3(new Pkt6(DHCPV6_SOLICIT, 1234));
query3->setRemoteAddr(IOAddress("fe80::abcd"));
query3->addOption(clientid);
query3->setIface("eth1");
query3->addOption(generateIA(D6O_IA_NA, 345, 1500, 3000));
Pkt6Ptr query1 = createSolicit();
Pkt6Ptr query2 = createSolicit();
Pkt6Ptr query3 = createSolicit();
// Create and add an ORO option to the first 2 queries
OptionUint16ArrayPtr oro(new OptionUint16Array(Option::V6, D6O_ORO));
......@@ -341,12 +339,7 @@ TEST_F(ClassifyTest, subnetClassPriority) {
// Create a packet with enough to select the subnet and go through
// the SOLICIT processing
Pkt6Ptr query(new Pkt6(DHCPV6_SOLICIT, 1234));
query->setRemoteAddr(IOAddress("fe80::abcd"));
OptionPtr clientid = generateClientId();
query->addOption(clientid);
query->setIface("eth1");
query->addOption(generateIA(D6O_IA_NA, 123, 1500, 3000));
Pkt6Ptr query = createSolicit();
// Create and add an ORO option to the query
OptionUint16ArrayPtr oro(new OptionUint16Array(Option::V6, D6O_ORO));
......@@ -413,12 +406,7 @@ TEST_F(ClassifyTest, subnetGlobalPriority) {
// Create a packet with enough to select the subnet and go through
// the SOLICIT processing
Pkt6Ptr query(new Pkt6(DHCPV6_SOLICIT, 1234));
query->setRemoteAddr(IOAddress("fe80::abcd"));
OptionPtr clientid = generateClientId();
query->addOption(clientid);
query->setIface("eth1");
query->addOption(generateIA(D6O_IA_NA, 123, 1500, 3000));
Pkt6Ptr query = createSolicit();
// Create and add an ORO option to the query
OptionUint16ArrayPtr oro(new OptionUint16Array(Option::V6, D6O_ORO));
......@@ -482,12 +470,7 @@ TEST_F(ClassifyTest, classGlobalPriority) {
// Create a packet with enough to select the subnet and go through
// the SOLICIT processing
Pkt6Ptr query(new Pkt6(DHCPV6_SOLICIT, 1234));
query->setRemoteAddr(IOAddress("fe80::abcd"));
OptionPtr clientid = generateClientId();
query->addOption(clientid);
query->setIface("eth1");
query->addOption(generateIA(D6O_IA_NA, 123, 1500, 3000));
Pkt6Ptr query = createSolicit();
// Create and add an ORO option to the query
OptionUint16ArrayPtr oro(new OptionUint16Array(Option::V6, D6O_ORO));
......@@ -558,12 +541,7 @@ TEST_F(ClassifyTest, classGlobalPersistency) {
// Create a packet with enough to select the subnet and go through
// the SOLICIT processing
Pkt6Ptr query(new Pkt6(DHCPV6_SOLICIT, 1234));
query->setRemoteAddr(IOAddress("fe80::abcd"));
OptionPtr clientid = generateClientId();
query->addOption(clientid);
query->setIface("eth1");
query->addOption(generateIA(D6O_IA_NA, 123, 1500, 3000));
Pkt6Ptr query = createSolicit();
// Do not add an ORO.
OptionPtr oro = query->getOption(D6O_ORO);
......@@ -620,11 +598,7 @@ TEST_F(ClassifyTest, clientClassifySubnet) {
ASSERT_NO_THROW(configure(config));
Pkt6Ptr sol = Pkt6Ptr(new Pkt6(DHCPV6_SOLICIT, 1234));
sol->setRemoteAddr(IOAddress("2001:db8:1::3"));
sol->addOption(generateIA(D6O_IA_NA, 234, 1500, 3000));
OptionPtr clientid = generateClientId();
sol->addOption(clientid);
Pkt6Ptr sol = createSolicit("2001:db8:1::3");
// This discover does not belong to foo class, so it will not
// be serviced
......@@ -685,22 +659,9 @@ TEST_F(ClassifyTest, clientClassifyPool) {
ASSERT_NO_THROW(configure(config));
OptionPtr clientid = generateClientId();
Pkt6Ptr query1 = Pkt6Ptr(new Pkt6(DHCPV6_SOLICIT, 1234));
query1->setRemoteAddr(IOAddress("2001:db8:1::3"));
query1->addOption(generateIA(D6O_IA_NA, 234, 1500, 3000));
query1->addOption(clientid);
query1->setIface("eth1");
Pkt6Ptr query2 = Pkt6Ptr(new Pkt6(DHCPV6_SOLICIT, 1234));
query2->setRemoteAddr(IOAddress("2001:db8:1::3"));
query2->addOption(generateIA(D6O_IA_NA, 234, 1500, 3000));
query2->addOption(clientid);
query2->setIface("eth1");
Pkt6Ptr query3 = Pkt6Ptr(new Pkt6(DHCPV6_SOLICIT, 1234));
query3->setRemoteAddr(IOAddress("2001:db8:1::3"));
query3->addOption(generateIA(D6O_IA_NA, 234, 1500, 3000));
query3->addOption(clientid);
query3->setIface("eth1");
Pkt6Ptr query1 = createSolicit("2001:db8:1::3");
Pkt6Ptr query2 = createSolicit("2001:db8:1::3");
Pkt6Ptr query3 = createSolicit("2001:db8:1::3");
// This discover does not belong to foo class, so it will not
// be serviced
......@@ -741,11 +702,7 @@ TEST_F(ClassifyTest, vendorClientClassification2) {
NakedDhcpv6Srv srv(0);
// Let's create a SOLICIT.
Pkt6Ptr sol = Pkt6Ptr(new Pkt6(DHCPV6_SOLICIT, 1234));
sol->setRemoteAddr(IOAddress("2001:db8:1::3"));
sol->addOption(generateIA(D6O_IA_NA, 234, 1500, 3000));
OptionPtr clientid = generateClientId();
sol->addOption(clientid);
Pkt6Ptr sol = createSolicit("2001:db8:1::3");
// Now let's add a vendor-class with id=1234 and content "foo"
OptionVendorClassPtr vendor_class(new OptionVendorClass(Option::V6, 1234));
......@@ -808,11 +765,7 @@ TEST_F(ClassifyTest, relayOverrideAndClientClass) {
ASSERT_TRUE(subnet1);
ASSERT_TRUE(subnet2);
Pkt6Ptr sol = Pkt6Ptr(new Pkt6(DHCPV6_SOLICIT, 1234));
sol->setRemoteAddr(IOAddress("2001:db8:1::3"));
sol->addOption(generateIA(D6O_IA_NA, 234, 1500, 3000));
OptionPtr clientid = generateClientId();
sol->addOption(clientid);
Pkt6Ptr sol = createSolicit("2001:db8:1::3");
// Now pretend the packet came via one relay.
Pkt6::RelayInfo relay;
......
This diff is collapsed.
......@@ -213,6 +213,7 @@ protected:
/// @todo: Implement this method
///
/// @param subnet an address will be picked from pool of that subnet
/// @param client_classes list of classes client belongs to
/// @param duid Client's DUID (ignored)
/// @param hint the last address that was picked (ignored)
/// @return a random address from the pool
......
......@@ -97,7 +97,7 @@ public:
return (cfg_option_);
}
/// @Checks whether this pool supports client that belongs to
/// @brief Checks whether this pool supports client that belongs to
/// specified classes.
///
/// @todo: currently doing the same than network which
......@@ -208,7 +208,7 @@ protected:
ClientClasses white_list_;
/// @brief Last allocated address
/// See @ref isc::dhcp::subnet::last_allocated_ia_
/// See @ref isc::dhcp::Subnet::last_allocated_ia_
/// Initialized and reset to first
isc::asiolink::IOAddress last_allocated_;
......
......@@ -315,12 +315,12 @@ protected:
/// @throw BadValue if invalid value is used
virtual void checkType(Lease::Type type) const = 0;
/// @brief returns a sum of possible leases in all pools
/// @brief Returns a sum of possible leases in all pools
/// @param pools list of pools
/// @return sum of possible leases
uint64_t sumPoolCapacity(const PoolCollection& pools) const;
/// @brief returns a sum of possible leases in all pools allowing classes
/// @brief Returns a sum of possible leases in all pools allowing classes
/// @param pools list of pools
/// @param client_classes list of classes
/// @return sum of possible/allowed leases
......
......@@ -638,7 +638,7 @@ TEST(Pool6Test, clientClass) {
TEST(Pool6Test, clientClasses) {
// Create a pool.
Pool6 pool(Lease::TYPE_NA, IOAddress("2001:db8::1"),
IOAddress("2001:db8::2"));
IOAddress("2001:db8::2"));
// This client does not belong to any class.
isc::dhcp::ClientClasses no_class;
......
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