"relay": {
"ip-address": "192.168.1.1"
}
- },
- {
- // This subnet is divided in two pools for unknown and
- // known (i.e. which have a reservation) clients.
- "pools": [
- {
- "pool": "192.0.8.100 - 192.0.8.200",
- "known-clients": "never"
- },
- {
- "pool": "192.0.9.100 - 192.0.9.200",
- "known-clients": "only"
- }
- ],
- "subnet": "192.0.8.0/23",
- "reservations": [
- { "hw-address": "00:00:00:11:22:33" },
- { "hw-address": "00:00:00:44:55:66" },
- { "hw-address": "00:00:00:77:88:99" },
- { "hw-address": "00:00:00:aa:bb:cc" }
- ]
}
]
},
"relay": {
"ip-address": "3000::1"
}
- },
- {
- // This subnet is divided in two pools for unknown and
- // known (i.e. which have a reservation) clients.
- "pools": [
- {
- "pool": "2001:db8:8::/64",
- "known-clients": "never"
- },
- {
- "pool": "2001:db8:9::/64",
- "known-clients": "only"
- }
- ],
- "subnet": "2001:db8:8::/46",
- "reservations": [
- { "hw-address": "00:00:00:11:22:33" },
- { "hw-address": "00:00:00:44:55:66" },
- { "hw-address": "00:00:00:77:88:99" },
- { "hw-address": "00:00:00:aa:bb:cc" }
- ]
}
]
},
</para>
<para>
- 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 four mechanisms that take
- advantage of client classification: subnet selection, definition of DHCPv4 private (codes 224-254) and code 43 options, assignment of different
- options and, for DHCPv4 cable modems, the setting of specific options for use with
- the TFTP server address and the boot file field.
+ At the opposite some clients can be grouped into a client class for
+ instance to get a common option.
</para>
<para>
- The process of doing classification is conducted in six steps:
+ An incoming packet can be associated with a client class in
+ serveral ways:
+ <itemizedlist>
+ <listitem><para>
+ Implicitely using a vendor class option or another builtin condition.
+ </para></listitem>
+ <listitem><para>
+ Using an expression which evaluates to true.
+ </para></listitem>
+ <listitem><para>
+ Using static host reservations, a shared network, a subnet, etc.
+ </para></listitem>
+ <listitem><para>
+ Using a hook.
+ </para></listitem>
+ </itemizedlist>
+ </para>
+
+ <para>
+ 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 five mechanisms that take advantage of
+ client classification: subnet selection, pool selection,
+ definition of DHCPv4 private (codes 224-254) and code 43
+ options, assignment of different options and, for DHCPv4 cable
+ modems, the setting of specific options for use with the TFTP
+ server address and the boot file field.
+ </para>
+
+ <para>
+ The process of doing classification is conducted in several steps:
<orderedlist>
<listitem><para>
- Assess an incoming packet and assign it to zero or more classes.
+ The ALL class is associated with the incoming packet.
+ </para></listitem>
+ <listitem><para>
+ Vendor class options are processed.
+ </para></listitem>
+ <listitem><para>
+ Classes with matching expressions and not marked for later
+ evaluation are processed in the order they are defined in the
+ configuration: the boolean expression is evaluated and when it
+ returns true ("match") the incoming packet is associated to the
+ class.
</para></listitem>
<listitem><para>
If a private or code 43 DHCPv4 option is received, decoding it
resort) definition.
</para></listitem>
<listitem><para>
- Choose a subnet, possibly based on the class information.
+ Choose a subnet, possibly based on the class information when
+ some subnets are guarded. More exactly: When choosing a subnet,
+ the server will iterate over all of the subnets that are
+ feasible given the information found in the packet (client
+ address, relay address etc). It will use the first subnet it
+ finds that either doesn't have a class associated with it or
+ that has a class which matches one of the packet's classes.
+ </para></listitem>
+ <listitem><para>
+ Host reservations are looked for. If an identifier from the incoming
+ packet matches a host reservation in the subnet or shared network,
+ the packet is associated with the KNOWN builtin class and all classes
+ of the host reservation.
</para></listitem>
<listitem><para>
- Assign classes from host reservations
+ Classes with matching expressions using directly or indirectly on
+ the KNOWN builtin class and not marked for only when required
+ evaluation are processed in the order they are defined in the
+ configuration: the boolean expression is evaluated and when it
+ returns true ("match") the incoming packet is associated to the
+ class.
</para></listitem>
<listitem><para>
- Perform a second pass by evaluating match expressions of on-demand
- classes.
+ If needed resources from pools are assigned, possibly based on the
+ class information when some pools are reserved to class members.
</para></listitem>
<listitem><para>
- Assign options, again possibly based on the class information.
+ Process required evaluation in the order classes are required
+ which uses the reverse precedence of option data: first shared
+ network, after the subnet and to finish pools assigned resources
+ belongs too.
+ </para></listitem>
+ <listitem><para>
+ Assign options, again possibly based on the class information
+ in order classes were associated with the incoming packet.
For DHCPv4 private and code 43 options this includes class local
option definitions.
</para></listitem>
</note>
<para>
- When determining which options to include in the response the server will examine
- the union of options from all of the assigned classes. In the case two or more
- classes include the same option, the value from the first class examined will
- be used. When choosing a subnet, the server will iterate over all of the
- subnets that are feasible given the information found in the packet (client address,
- relay address etc). It will use the first subnet it finds that either doesn't
- have a class associated with it or that has a class which matches one of
- the packet's classes. In the future the processing order of the
- various classes may be specified but for now it is being left unspecified and
- may change in future releases.
+ When determining which options to include in the response the
+ server will examine the union of options from all of the
+ assigned classes. In the case two or more classes include the
+ same option, the value from the first class examined will be
+ used, and classes are examined in the order they were associated
+ so ALL is always the first class and matching required classes
+ are last.
</para>
<para>
- As an example, imagine that an incoming packet matches two classes.
- Class "foo" defines values for an NTP server
- (option 42 in DHCPv4) and an SMTP server (option 69 in DHCPv4) while class
- "bar" defines values for an NTP server and a POP3 server (option 70 in DHCPv4).
- The server will examine the three options NTP, SMTP and POP3 and return any
- of them that the client requested. As the NTP server was defined twice the
- server will choose only one of the values for the reply: the class from which the
- value is obtained is unspecified.
- </para>
-
- <para>
- There are two methods of doing classification. The first is automatic and relies
- on examining the values in the vendor class options. Information from these
- options is extracted and a class name is constructed from it and added to
- the class list for the packet. The second allows you to specify an expression
- that is evaluated for each packet. If the result is true, the packet is
- a member of the class.
+ As an example, imagine that an incoming packet matches two
+ classes. Class "foo" defines values for an NTP server (option
+ 42 in DHCPv4) and an SMTP server (option 69 in DHCPv4) while
+ class "bar" defines values for an NTP server and a POP3 server
+ (option 70 in DHCPv4). The server will examine the three
+ options NTP, SMTP and POP3 and return any of them that the
+ client requested. As the NTP server was defined twice the
+ server will choose only one of the values for the reply: the
+ class from which the value is obtained is unspecified.
</para>
<note>
</note>
</section>
- <section id="classification-using-host-reservations">
- <title>Using Static Host Reservations In Classification</title>
- <para>Classes can be statically assigned to the clients using techniques described
- in <xref linkend="reservation4-client-classes"/> and
- <xref linkend="reservation6-client-classes"/>.
- </para>
- </section>
-
<section id="classification-using-vendor">
- <title>Using Vendor Class Information In Classification</title>
+ <title>Builtin Client Classes</title>
<para>
- The server checks whether an incoming DHCPv4 packet includes
- the vendor class identifier option (60) or an incoming DHCPv6 packet
- includes the vendor class option (16). If it does, the content of that
- option is prepended with "VENDOR_CLASS_" and the result is interpreted
- as a class. For example, modern cable modems will send this option with
- value "docsis3.0" and so the packet will belong to
- class "VENDOR_CLASS_docsis3.0".
+ Some classes are builtin so do not need to be defined. The main
+ example uses Vendor Class information: The server checks whether
+ an incoming DHCPv4 packet includes the vendor class identifier
+ option (60) or an incoming DHCPv6 packet includes the vendor
+ class option (16). If it does, the content of that option is
+ prepended with "VENDOR_CLASS_" and the result is
+ interpreted as a class. For example, modern cable modems will
+ send this option with value "docsis3.0" and so the
+ packet will belong to class "VENDOR_CLASS_docsis3.0".
+ </para>
+
+ <para>Other examples are the ALL class what all incoming packets
+ belongs to, and the KNOWN class. By convention builtin classes
+ names begin with all caps.
</para>
</section>
<section id="classification-using-expressions">
<title>Using Expressions In Classification</title>
<para>
- The expression portion of classification contains operators and values.
- All values are currently strings and operators take a string or strings and
- return another string. When all the operations have completed
- the result should be a value of "true" or "false".
- The packet belongs to
- the class (and the class name is added to the list of classes) if the result
- is "true". Expressions are written in standard format and can be nested.
- </para>
-
- <para>
- When the eval-on-demand flag is set to true in a class definition,
- the match expression is skipped during the first evaluation pass.
+ The expression portion of classification contains operators and
+ values. All values are currently strings and operators take a
+ string or strings and return another string. When all the
+ operations have completed the result should be a value of
+ "true" or "false". The packet belongs to
+ the class (and the class name is added to the list of classes)
+ if the result is "true". Expressions are written in
+ standard format and can be nested.
</para>
<para>
- Expressions are pre-processed during the parsing of the configuration file
- and converted to an internal representation. This allows certain types of
- errors to be caught and logged during parsing. Examples of these errors
- include an incorrect number or types of arguments to an operator. The
- evaluation code will also check for this class of error and generally
- throw an exception, though this should not occur in a normally functioning
- system.
+ Expressions are pre-processed during the parsing of the
+ configuration file and converted to an internal
+ representation. This allows certain types of errors to be caught
+ and logged during parsing. Examples of these errors include an
+ incorrect number or types of arguments to an operator. The
+ evaluation code will also check for this class of error and
+ generally throw an exception, though this should not occur in a
+ normally functioning system.
</para>
<para>
remain the same.
</para>
+ <para>
+ Dependencies between classes are checked too: for instance forward
+ dependencies are rejected when the configuration is parsed:
+ an expression can only depends on already defined classes (including
+ builtin classes) and which are evaluated in a previous or the
+ same evaluation phase. This does not apply to the KNOWN class.
+ </para>
+
<para>
<table frame="all" id="classification-values-list">
<title>List of Classification Values</title>
<entry>If the packet belongs to the given client class
"true" else "false"</entry>
</row>
+ <row>
+ <entry>Known client</entry>
+ <entry>known</entry>
+ <entry>member('KNOWN')</entry>
+ <entry>If there is a host reservation for the client
+ "true" else "false"</entry>
+ </row>
+ <row>
+ <entry>Unknown client</entry>
+ <entry>unknown</entry>
+ <entry>not member('KNOWN')</entry>
+ <entry>If there is a hostreservation for the client
+ "false" else "true"</entry>
+ </row>
<row>
<entry>DHCPv4 relay agent sub-option</entry>
<entry>relay4[123].hex</entry>
parser checks if client classes were already defined or are
built-in, i.e., beginning by "VENDOR_CLASS_",
"AFTER__" (for the to come "after" hook) and
- "EXTERNAL_".
+ "EXTERNAL_" or equal to "ALL", "KNOWN",
+ etc.
+ </para>
+ <para>"known" and "unknown" are short hands for "member('KNOWN')" and
+ "not member('KNOWN')". Note the evaluation of any expression using
+ directly or indirectly the "KNOWN" class is deferred
+ after the host reservation lookup (i.e. when the "KNOWN"
+ belonging is determined).
</para></listitem>
<listitem><para>
</para>
</section>
+ <section id="classification-using-host-reservations">
+ <title>Using Static Host Reservations In Classification</title>
+ <para>Classes can be statically assigned to the clients using techniques described
+ in <xref linkend="reservation4-client-classes"/> and
+ <xref linkend="reservation6-client-classes"/>.
+ </para>
+ </section>
+
<section id="classification-subnets">
<title>Configuring Subnets With Class Information</title>
<para>
at the pool level, see <xref linkend="classification-pools"/>.
</para>
- <para>
- In a similar way a pool can be constrained to serve only known clients,
- i.e. clients which have a reservation, using
- <command>"known-clients": "only"</command>, or only unknown clients
- with <command>"known-clients": "never"</command>. One can assign
- addresses to registered clients without giving a different address per
- reservations, for instance when there is not enough available addresses.
- </para>
-
<para>
The process of doing classification is conducted in five steps. The first step
is to assess an incoming packet and assign it to zero or more classes. The
linkend="classification-pools"/>.
</para>
- <para>
- In a similar way a pool can be constrained to serve only known clients,
- i.e. clients which have a reservation, using
- <command>"known-clients": "only"</command>, or only unknown clients
- with <command>"known-clients": "never"</command>. One can assign
- prefixes to registered clients without giving a different prefix per
- reservations, forinstance when there is not enough available prefixes.
- </para>
-
<para>
The process of doing classification is conducted in five steps. The first step
is to assess an incoming packet and assign it to zero or more classes. The
-/* Copyright (C) 2016-2017 Internet Systems Consortium, Inc. ("ISC")
+/* Copyright (C) 2016-2018 Internet Systems Consortium, Inc. ("ISC")
This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
}
}
-\"known-clients\" {
- switch(driver.ctx_) {
- case isc::dhcp::Parser4Context::POOLS:
- return isc::dhcp::Dhcp4Parser::make_KNOWN_CLIENTS(driver.loc_);
- default:
- return isc::dhcp::Dhcp4Parser::make_STRING("known-clients", driver.loc_);
- }
-}
-
-\"only\" {
- switch(driver.ctx_) {
- case isc::dhcp::Parser4Context::KNOWN_CLIENTS:
- return isc::dhcp::Dhcp4Parser::make_ONLY(driver.loc_);
- default:
- return isc::dhcp::Dhcp4Parser::make_STRING("only", driver.loc_);
- }
-}
-
\"never\" {
switch(driver.ctx_) {
- case isc::dhcp::Parser4Context::KNOWN_CLIENTS:
case isc::dhcp::Parser4Context::REPLACE_CLIENT_NAME:
return isc::dhcp::Dhcp4Parser::make_NEVER(driver.loc_);
default:
-/* Copyright (C) 2016-2017 Internet Systems Consortium, Inc. ("ISC")
+/* Copyright (C) 2016-2018 Internet Systems Consortium, Inc. ("ISC")
This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
POOLS "pools"
POOL "pool"
USER_CONTEXT "user-context"
- KNOWN_CLIENTS "known-clients"
- ONLY "only"
- NEVER "never"
SUBNET "subnet"
INTERFACE "interface"
TCP "tcp"
JSON "JSON"
WHEN_PRESENT "when-present"
+ NEVER "never"
ALWAYS "always"
WHEN_NOT_PRESENT "when-not-present"
%type <ElementPtr> outbound_interface_value
%type <ElementPtr> db_type
%type <ElementPtr> hr_mode
-%type <ElementPtr> known_clients_value
%type <ElementPtr> ncr_protocol_value
%type <ElementPtr> replace_client_name_value
| client_class
| eval_client_classes
| user_context
- | known_clients
| unknown_map_entry
;
ctx.leave();
};
-known_clients: KNOWN_CLIENTS {
- ctx.enter(ctx.KNOWN_CLIENTS);
-} COLON known_clients_value {
- ctx.stack_.back()->set("known-clients", $4);
- ctx.leave();
-}
-
-known_clients_value:
- ONLY { $$ = ElementPtr(new StringElement("only", ctx.loc2pos(@1))); }
- | NEVER { $$ = ElementPtr(new StringElement("never", ctx.loc2pos(@1))); }
-;
-
// --- end of pools definition -------------------------------
// --- reservations ------------------------------------------
-// Copyright (C) 2016-2017 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2016-2018 Internet Systems Consortium, Inc. ("ISC")
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
return ("control-socket");
case POOLS:
return ("pools");
- case KNOWN_CLIENTS:
- return ("known-clients");
case RESERVATIONS:
return ("reservations");
case RELAY:
-// Copyright (C) 2015-2017 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2015-2018 Internet Systems Consortium, Inc. ("ISC")
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
/// Used while parsing Dhcp4/subnet4/pools structures.
POOLS,
- /// Used while parsing Dhcp4/subnet4/pools/known_client structures.
- KNOWN_CLIENTS,
-
/// Used while parsing Dhcp4/reservations structures.
RESERVATIONS,
EXPECT_TRUE (subnets->at(3)->clientSupported(classes));
}
-// Goal of this test is to verify that multiple pools can be configured
-// with defined client classes.
-TEST_F(Dhcp4ParserTest, classifyPools) {
- ConstElementPtr x;
- string config = "{ " + genIfaceConfig() + "," +
- "\"rebind-timer\": 2000, "
- "\"renew-timer\": 1000, "
- "\"subnet4\": [ { "
- " \"pools\": [ { "
- " \"pool\": \"192.0.2.1 - 192.0.2.100\", "
- " \"client-class\": \"alpha\" "
- " },"
- " {"
- " \"pool\": \"192.0.3.101 - 192.0.3.150\", "
- " \"client-class\": \"beta\", "
- " \"known-clients\": \"never\" "
- " },"
- " {"
- " \"pool\": \"192.0.4.101 - 192.0.4.150\", "
- " \"client-class\": \"gamma\", "
- " \"known-clients\": \"only\" "
- " },"
- " {"
- " \"pool\": \"192.0.5.101 - 192.0.5.150\" "
- " } ],"
- " \"subnet\": \"192.0.0.0/16\" "
- " } ],"
- "\"valid-lifetime\": 4000 }";
-
- ConstElementPtr json;
- ASSERT_NO_THROW(json = parseDHCP4(config, true));
- extractConfig(config);
-
- EXPECT_NO_THROW(x = configureDhcp4Server(*srv_, json));
- checkResult(x, 0);
-
- const Subnet4Collection* subnets =
- CfgMgr::instance().getStagingCfg()->getCfgSubnets4()->getAll();
- ASSERT_TRUE(subnets);
- ASSERT_EQ(1, subnets->size());
- const PoolCollection& pools = subnets->at(0)->getPools(Lease::TYPE_V4);
- ASSERT_EQ(4, pools.size()); // We expect 4 pools
-
- // Let's check if client belonging to alpha class is supported in pool[0]
- // and not supported in any other pool (except pool[3], which allows
- // everyone).
- ClientClasses classes;
- classes.insert("alpha");
- EXPECT_TRUE(pools.at(0)->clientSupported(classes, false));
- EXPECT_TRUE(pools.at(0)->clientSupported(classes, true));
- EXPECT_FALSE(pools.at(1)->clientSupported(classes, false));
- EXPECT_FALSE(pools.at(1)->clientSupported(classes, true));
- EXPECT_FALSE(pools.at(2)->clientSupported(classes, false));
- EXPECT_FALSE(pools.at(2)->clientSupported(classes, true));
- EXPECT_TRUE(pools.at(3)->clientSupported(classes, false));
- EXPECT_TRUE(pools.at(3)->clientSupported(classes, true));
-
- // Let's check if client belonging to beta class is supported in pool[1]
- // and not supported in any other pool (except pools[3], which allows
- // everyone).
- classes.clear();
- classes.insert("beta");
- EXPECT_FALSE(pools.at(0)->clientSupported(classes, false));
- EXPECT_FALSE(pools.at(0)->clientSupported(classes, true));
- EXPECT_TRUE(pools.at(1)->clientSupported(classes, false));
- EXPECT_FALSE(pools.at(1)->clientSupported(classes, true));
- EXPECT_FALSE(pools.at(2)->clientSupported(classes, false));
- EXPECT_FALSE(pools.at(2)->clientSupported(classes, true));
- EXPECT_TRUE(pools.at(3)->clientSupported(classes, false));
- EXPECT_TRUE(pools.at(3)->clientSupported(classes, true));
-
- // Let's check if client belonging to gamma class is supported in pool[2]
- // and not supported in any other pool (except pool[3], which allows
- // everyone).
- classes.clear();
- classes.insert("gamma");
- EXPECT_FALSE(pools.at(0)->clientSupported(classes, false));
- EXPECT_FALSE(pools.at(0)->clientSupported(classes, true));
- EXPECT_FALSE(pools.at(1)->clientSupported(classes, false));
- EXPECT_FALSE(pools.at(1)->clientSupported(classes, true));
- EXPECT_FALSE(pools.at(2)->clientSupported(classes, false));
- EXPECT_TRUE(pools.at(2)->clientSupported(classes, true));
- EXPECT_TRUE(pools.at(3)->clientSupported(classes, false));
- EXPECT_TRUE(pools.at(3)->clientSupported(classes, true));
-
- // Let's check if client belonging to some other class (not mentioned in
- // the config) is supported only in pool[3], which allows everyone.
- classes.clear();
- classes.insert("delta");
- EXPECT_FALSE(pools.at(0)->clientSupported(classes, false));
- EXPECT_FALSE(pools.at(0)->clientSupported(classes, true));
- EXPECT_FALSE(pools.at(1)->clientSupported(classes, false));
- EXPECT_FALSE(pools.at(1)->clientSupported(classes, true));
- EXPECT_FALSE(pools.at(2)->clientSupported(classes, false));
- EXPECT_FALSE(pools.at(2)->clientSupported(classes, true));
- EXPECT_TRUE(pools.at(3)->clientSupported(classes, false));
- EXPECT_TRUE(pools.at(3)->clientSupported(classes, true));
-
- // Finally, let's check class-less client. He should be allowed only in
- // the last pool, which does not have any class restrictions.
- classes.clear();
- EXPECT_FALSE(pools.at(0)->clientSupported(classes, false));
- EXPECT_FALSE(pools.at(0)->clientSupported(classes, true));
- EXPECT_FALSE(pools.at(1)->clientSupported(classes, false));
- EXPECT_FALSE(pools.at(1)->clientSupported(classes, true));
- EXPECT_FALSE(pools.at(2)->clientSupported(classes, false));
- EXPECT_FALSE(pools.at(2)->clientSupported(classes, true));
- EXPECT_TRUE(pools.at(3)->clientSupported(classes, false));
- EXPECT_TRUE(pools.at(3)->clientSupported(classes, true));
-}
-
// This test verifies that the host reservations can be specified for
// respective IPv4 subnets.
TEST_F(Dhcp4ParserTest, reservations) {
EXPECT_FALSE(offer->getYiaddr().isV4Zero());
}
-// Checks if the known-clients field is indeed used for pool selection.
-TEST_F(Dhcpv4SrvTest, clientPoolKnown) {
- IfaceMgrTestConfig test_config(true);
- IfaceMgr::instance().openSockets4();
-
- NakedDhcpv4Srv srv(0);
-
- // This test configures 2 pools.
- string config = "{ \"interfaces-config\": {"
- " \"interfaces\": [ \"*\" ]"
- "},"
- "\"rebind-timer\": 2000, "
- "\"renew-timer\": 1000, "
- "\"subnet4\": [ "
- "{ \"pools\": [ { "
- " \"pool\": \"192.0.2.1 - 192.0.2.100\", "
- " \"known-clients\": \"only\" }, "
- " { \"pool\": \"192.0.3.1 - 192.0.3.100\", "
- " \"known-clients\": \"never\" } ], "
- " \"subnet\": \"192.0.0.0/16\" } "
- "],"
- "\"valid-lifetime\": 4000 }";
-
- ConstElementPtr json;
- ASSERT_NO_THROW(json = parseDHCP4(config, true));
-
- ConstElementPtr status;
- EXPECT_NO_THROW(status = configureDhcp4Server(srv, json));
-
- CfgMgr::instance().commit();
-
- // check if returned status is OK
- ASSERT_TRUE(status);
- comment_ = config::parseAnswer(rcode_, status);
- ASSERT_EQ(0, rcode_);
-
- // Create a simple packet
- Pkt4Ptr dis = Pkt4Ptr(new Pkt4(DHCPDISCOVER, 1234));
- dis->setRemoteAddr(IOAddress("192.0.2.1"));
- dis->setCiaddr(IOAddress("192.0.2.1"));
- dis->setIface("eth0");
- OptionPtr clientid = generateClientId();
- dis->addOption(clientid);
-
- // First pool requires reservation so the second will be used
- Pkt4Ptr offer = srv.processDiscover(dis);
- ASSERT_TRUE(offer);
- EXPECT_EQ(DHCPOFFER, offer->getType());
- EXPECT_EQ("192.0.3.1", offer->getYiaddr().toText());
-}
-
// Verifies last resort option 43 is backward compatible
TEST_F(Dhcpv4SrvTest, option43LastResort) {
IfaceMgrTestConfig test_config(true);
-/* Copyright (C) 2016-2017 Internet Systems Consortium, Inc. ("ISC")
+/* Copyright (C) 2016-2018 Internet Systems Consortium, Inc. ("ISC")
This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
\"never\" {
switch(driver.ctx_) {
- case isc::dhcp::Parser6Context::KNOWN_CLIENTS:
case isc::dhcp::Parser6Context::REPLACE_CLIENT_NAME:
return isc::dhcp::Dhcp6Parser::make_NEVER(driver.loc_);
default:
}
}
-\"known-clients\" {
- switch(driver.ctx_) {
- case isc::dhcp::Parser6Context::POOLS:
- case isc::dhcp::Parser6Context::PD_POOLS:
- return isc::dhcp::Dhcp6Parser::make_KNOWN_CLIENTS(driver.loc_);
- default:
- return isc::dhcp::Dhcp6Parser::make_STRING("known-clients", driver.loc_);
- }
-}
-
-\"only\" {
- switch(driver.ctx_) {
- case isc::dhcp::Parser6Context::KNOWN_CLIENTS:
- return isc::dhcp::Dhcp6Parser::make_ONLY(driver.loc_);
- default:
- return isc::dhcp::Dhcp6Parser::make_STRING("only", driver.loc_);
- }
-}
-
\"subnet\" {
switch(driver.ctx_) {
case isc::dhcp::Parser6Context::SUBNET6:
-/* Copyright (C) 2016-2017 Internet Systems Consortium, Inc. ("ISC")
+/* Copyright (C) 2016-2018 Internet Systems Consortium, Inc. ("ISC")
This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
EXCLUDED_PREFIX_LEN "excluded-prefix-len"
DELEGATED_LEN "delegated-len"
USER_CONTEXT "user-context"
- KNOWN_CLIENTS "known-clients"
- ONLY "only"
- NEVER "never"
SUBNET "subnet"
INTERFACE "interface"
TCP "TCP"
JSON "JSON"
WHEN_PRESENT "when-present"
+ NEVER "never"
ALWAYS "always"
WHEN_NOT_PRESENT "when-not-present"
%type <ElementPtr> map_value
%type <ElementPtr> db_type
%type <ElementPtr> hr_mode
-%type <ElementPtr> known_clients_value
%type <ElementPtr> duid_type
%type <ElementPtr> ncr_protocol_value
%type <ElementPtr> replace_client_name_value
| client_class
| eval_client_classes
| user_context
- | known_clients
| unknown_map_entry
;
ctx.leave();
};
-known_clients: KNOWN_CLIENTS {
- ctx.enter(ctx.KNOWN_CLIENTS);
-} COLON known_clients_value {
- ctx.stack_.back()->set("known-clients", $4);
- ctx.leave();
-}
-
-known_clients_value:
- ONLY { $$ = ElementPtr(new StringElement("only", ctx.loc2pos(@1))); }
- | NEVER { $$ = ElementPtr(new StringElement("never", ctx.loc2pos(@1))); }
-;
-
// --- end of pools definition -------------------------------
// --- pd-pools ----------------------------------------------
| excluded_prefix
| excluded_prefix_len
| user_context
- | known_clients
| unknown_map_entry
;
-// Copyright (C) 2016-2017 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2016-2018 Internet Systems Consortium, Inc. ("ISC")
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
return ("pools");
case PD_POOLS:
return ("pd-pools");
- case KNOWN_CLIENTS:
- return ("known-clients");
case RESERVATIONS:
return ("reservations");
case RELAY:
-// Copyright (C) 2015-2017 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2015-2018 Internet Systems Consortium, Inc. ("ISC")
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
/// Used while parsing Dhcp6/subnet6/pd-pools structures.
PD_POOLS,
- /// Used while parsing Dhcp4/subnet6/pools/known_client structures.
- KNOWN_CLIENTS,
-
/// Used while parsing Dhcp6/reservations structures.
RESERVATIONS,
EXPECT_TRUE(ia_na3->getOption(D6O_IAADDR));
}
-// Checks if the known-clients field is indeed used for pool selection.
-TEST_F(ClassifyTest, clientKnownPool) {
- IfaceMgrTestConfig test_config(true);
-
- NakedDhcpv6Srv srv(0);
-
- // This test configures 2 pools.
- std::string config = "{ \"interfaces-config\": {"
- " \"interfaces\": [ \"*\" ]"
- "},"
- "\"preferred-lifetime\": 3000,"
- "\"rebind-timer\": 2000, "
- "\"renew-timer\": 1000, "
- "\"client-classes\": [ "
- " { "
- " \"name\": \"foo\" "
- " }, "
- " { "
- " \"name\": \"bar\" "
- " } "
- "], "
- "\"subnet6\": [ "
- " { \"pools\": [ "
- " { "
- " \"pool\": \"2001:db8:1::/64\", "
- " \"known-clients\": \"only\" "
- " }, "
- " { "
- " \"pool\": \"2001:db8:2::/64\", "
- " \"known-clients\": \"never\" "
- " } "
- " ], "
- " \"subnet\": \"2001:db8:2::/40\", "
- " \"reservations\": [ "
- " { \"duid\": \"01:02:03:04\", \"hostname\": \"foo\" } ] "
- " } "
- "], "
- "\"valid-lifetime\": 4000 }";
-
- ASSERT_NO_THROW(configure(config));
-
- OptionPtr clientid1 = 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(clientid1);
- query1->setIface("eth1");
-
- // First pool requires reservation so the second will be used
- srv.classifyPacket(query1);
- Pkt6Ptr response1 = srv.processSolicit(query1);
- ASSERT_TRUE(response1);
- OptionPtr ia_na1 = response1->getOption(D6O_IA_NA);
- ASSERT_TRUE(ia_na1);
- EXPECT_FALSE(ia_na1->getOption(D6O_STATUS_CODE));
- OptionPtr iaaddr1 = ia_na1->getOption(D6O_IAADDR);
- ASSERT_TRUE(iaaddr1);
- boost::shared_ptr<Option6IAAddr> addr1 =
- boost::dynamic_pointer_cast<Option6IAAddr>(iaaddr1);
- ASSERT_TRUE(addr1);
- EXPECT_EQ("2001:db8:2::", addr1->getAddress().toText());
-
- // Try with DUID 01:02:03:04
- uint8_t duid[] = { 0x01, 0x02, 0x03, 0x04 };
- OptionBuffer buf(duid, duid + sizeof(duid));
- OptionPtr clientid2(new Option(Option::V6, D6O_CLIENTID, buf));
- Pkt6Ptr query2 = Pkt6Ptr(new Pkt6(DHCPV6_SOLICIT, 2345));
- query2->setRemoteAddr(IOAddress("2001:db8:1::3"));
- query2->addOption(generateIA(D6O_IA_NA, 234, 1500, 3000));
- query2->addOption(clientid2);
- query2->setIface("eth1");
-
- // Now the first pool will be used
- srv.classifyPacket(query2);
- Pkt6Ptr response2 = srv.processSolicit(query2);
- ASSERT_TRUE(response2);
- OptionPtr ia_na2 = response2->getOption(D6O_IA_NA);
- ASSERT_TRUE(ia_na2);
- EXPECT_FALSE(ia_na2->getOption(D6O_STATUS_CODE));
- OptionPtr iaaddr2 = ia_na2->getOption(D6O_IAADDR);
- ASSERT_TRUE(iaaddr2);
- boost::shared_ptr<Option6IAAddr> addr2 =
- boost::dynamic_pointer_cast<Option6IAAddr>(iaaddr2);
- ASSERT_TRUE(addr2);
- EXPECT_EQ("2001:db8:1::", addr2->getAddress().toText());
-}
-
// Tests whether a packet with custom vendor-class (not erouter or docsis)
// is classified properly.
TEST_F(ClassifyTest, vendorClientClassification2) {
EXPECT_TRUE (subnets->at(3)->clientSupported(classes));
}
-// Goal of this test is to verify that multiple pools can be configured
-// with defined client classes.
-TEST_F(Dhcp6ParserTest, classifyPools) {
- ConstElementPtr x;
- string config = "{ " + genIfaceConfig() + ","
- "\"preferred-lifetime\": 3000,"
- "\"rebind-timer\": 2000, "
- "\"renew-timer\": 1000, "
- "\"subnet6\": [ { "
- " \"pools\": [ { "
- " \"pool\": \"2001:db8:1::/80\", "
- " \"client-class\": \"alpha\" "
- " },"
- " {"
- " \"pool\": \"2001:db8:2::/80\", "
- " \"client-class\": \"beta\", "
- " \"known-clients\": \"never\" "
- " },"
- " {"
- " \"pool\": \"2001:db8:3::/80\", "
- " \"client-class\": \"gamma\", "
- " \"known-clients\": \"only\" "
- " },"
- " {"
- " \"pool\": \"2001:db8:4::/80\" "
- " } ],"
- " \"subnet\": \"2001:db8:0::/40\" "
- " } ],"
- "\"valid-lifetime\": 4000 }";
-
- ConstElementPtr json;
- ASSERT_NO_THROW(json = parseDHCP6(config, true));
- extractConfig(config);
-
- EXPECT_NO_THROW(x = configureDhcp6Server(srv_, json));
- checkResult(x, 0);
-
- const Subnet6Collection* subnets =
- CfgMgr::instance().getStagingCfg()->getCfgSubnets6()->getAll();
- ASSERT_TRUE(subnets);
- ASSERT_EQ(1, subnets->size());
- const PoolCollection& pools = subnets->at(0)->getPools(Lease::TYPE_NA);
- ASSERT_EQ(4, pools.size()); // We expect 4 pools
-
- // Let's check if client belonging to alpha class is supported in pool[0]
- // and not supported in any other pool (except pool[3], which allows
- // everyone).
- ClientClasses classes;
- classes.insert("alpha");
- EXPECT_TRUE(pools.at(0)->clientSupported(classes, false));
- EXPECT_TRUE(pools.at(0)->clientSupported(classes, true));
- EXPECT_FALSE(pools.at(1)->clientSupported(classes, false));
- EXPECT_FALSE(pools.at(1)->clientSupported(classes, true));
- EXPECT_FALSE(pools.at(2)->clientSupported(classes, false));
- EXPECT_FALSE(pools.at(2)->clientSupported(classes, true));
- EXPECT_TRUE(pools.at(3)->clientSupported(classes, false));
- EXPECT_TRUE(pools.at(3)->clientSupported(classes, true));
-
- // Let's check if client belonging to beta class is supported in pool[1]
- // and not supported in any other pool (except pool[3], which allows
- // everyone).
- classes.clear();
- classes.insert("beta");
- EXPECT_FALSE(pools.at(0)->clientSupported(classes, false));
- EXPECT_FALSE(pools.at(0)->clientSupported(classes, true));
- EXPECT_TRUE(pools.at(1)->clientSupported(classes, false));
- EXPECT_FALSE(pools.at(1)->clientSupported(classes, true));
- EXPECT_FALSE(pools.at(2)->clientSupported(classes, false));
- EXPECT_FALSE(pools.at(2)->clientSupported(classes, true));
- EXPECT_TRUE(pools.at(3)->clientSupported(classes, false));
- EXPECT_TRUE(pools.at(3)->clientSupported(classes, true));
-
- // Let's check if client belonging to gamma class is supported in pool[2]
- // and not supported in any other pool (except pool[3], which allows
- // everyone).
- classes.clear();
- classes.insert("gamma");
- EXPECT_FALSE(pools.at(0)->clientSupported(classes, false));
- EXPECT_FALSE(pools.at(0)->clientSupported(classes, true));
- EXPECT_FALSE(pools.at(1)->clientSupported(classes, false));
- EXPECT_FALSE(pools.at(1)->clientSupported(classes, true));
- EXPECT_FALSE(pools.at(2)->clientSupported(classes, false));
- EXPECT_TRUE(pools.at(2)->clientSupported(classes, true));
- EXPECT_TRUE(pools.at(3)->clientSupported(classes, false));
- EXPECT_TRUE(pools.at(3)->clientSupported(classes, true));
-
- // Let's check if client belonging to some other class (not mentioned in
- // the config) is supported only in pool[3], which allows everyone.
- classes.clear();
- classes.insert("delta");
- EXPECT_FALSE(pools.at(0)->clientSupported(classes, false));
- EXPECT_FALSE(pools.at(0)->clientSupported(classes, true));
- EXPECT_FALSE(pools.at(1)->clientSupported(classes, false));
- EXPECT_FALSE(pools.at(1)->clientSupported(classes, true));
- EXPECT_FALSE(pools.at(2)->clientSupported(classes, false));
- EXPECT_FALSE(pools.at(2)->clientSupported(classes, true));
- EXPECT_TRUE(pools.at(3)->clientSupported(classes, false));
- EXPECT_TRUE(pools.at(3)->clientSupported(classes, true));
-
- // Finally, let's check class-less client. He should be allowed only in
- // the last pool, which does not have any class restrictions.
- classes.clear();
- EXPECT_FALSE(pools.at(0)->clientSupported(classes, false));
- EXPECT_FALSE(pools.at(0)->clientSupported(classes, true));
- EXPECT_FALSE(pools.at(1)->clientSupported(classes, false));
- EXPECT_FALSE(pools.at(1)->clientSupported(classes, true));
- EXPECT_FALSE(pools.at(2)->clientSupported(classes, false));
- EXPECT_FALSE(pools.at(2)->clientSupported(classes, true));
- EXPECT_TRUE(pools.at(3)->clientSupported(classes, false));
- EXPECT_TRUE(pools.at(3)->clientSupported(classes, true));
-}
-
-// Goal of this test is to verify that multiple pdpools can be configured
-// with defined client classes.
-TEST_F(Dhcp6ParserTest, classifyPdPools) {
- ConstElementPtr x;
- string config = "{ " + genIfaceConfig() + ","
- "\"preferred-lifetime\": 3000,"
- "\"rebind-timer\": 2000, "
- "\"renew-timer\": 1000, "
- "\"subnet6\": [ { "
- " \"pd-pools\": [ { "
- " \"prefix-len\": 48, "
- " \"delegated-len\": 64, "
- " \"prefix\": \"2001:db8:1::\", "
- " \"client-class\": \"alpha\" "
- " },"
- " {"
- " \"prefix-len\": 48, "
- " \"delegated-len\": 64, "
- " \"prefix\": \"2001:db8:2::\", "
- " \"client-class\": \"beta\", "
- " \"known-clients\": \"never\" "
- " },"
- " {"
- " \"prefix-len\": 48, "
- " \"delegated-len\": 64, "
- " \"prefix\": \"2001:db8:3::\", "
- " \"client-class\": \"gamma\", "
- " \"known-clients\": \"only\" "
- " },"
- " {"
- " \"prefix-len\": 48, "
- " \"delegated-len\": 64, "
- " \"prefix\": \"2001:db8:4::\" "
- " } ],"
- " \"subnet\": \"2001:db8::/64\" "
- " } ],"
- "\"valid-lifetime\": 4000 }";
-
- ConstElementPtr json;
- ASSERT_NO_THROW(json = parseDHCP6(config, true));
- extractConfig(config);
-
- EXPECT_NO_THROW(x = configureDhcp6Server(srv_, json));
- checkResult(x, 0);
-
- const Subnet6Collection* subnets =
- CfgMgr::instance().getStagingCfg()->getCfgSubnets6()->getAll();
- ASSERT_TRUE(subnets);
- ASSERT_EQ(1, subnets->size());
- const PoolCollection& pools = subnets->at(0)->getPools(Lease::TYPE_PD);
- ASSERT_EQ(4, pools.size()); // We expect 4 pools
-
- // Let's check if client belonging to alpha class is supported in pool[0]
- // and not supported in any other pool (except pool[3], which allows
- // everyone).
- ClientClasses classes;
- classes.insert("alpha");
- EXPECT_TRUE(pools.at(0)->clientSupported(classes, false));
- EXPECT_TRUE(pools.at(0)->clientSupported(classes, true));
- EXPECT_FALSE(pools.at(1)->clientSupported(classes, false));
- EXPECT_FALSE(pools.at(1)->clientSupported(classes, true));
- EXPECT_FALSE(pools.at(2)->clientSupported(classes, false));
- EXPECT_FALSE(pools.at(2)->clientSupported(classes, true));
- EXPECT_TRUE(pools.at(3)->clientSupported(classes, false));
- EXPECT_TRUE(pools.at(3)->clientSupported(classes, true));
-
- // Let's check if client belonging to beta class is supported in pool[1]
- // and not supported in any other pool (except pool[3], which allows
- // everyone).
- classes.clear();
- classes.insert("beta");
- EXPECT_FALSE(pools.at(0)->clientSupported(classes, false));
- EXPECT_FALSE(pools.at(0)->clientSupported(classes, true));
- EXPECT_TRUE(pools.at(1)->clientSupported(classes, false));
- EXPECT_FALSE(pools.at(1)->clientSupported(classes, true));
- EXPECT_FALSE(pools.at(2)->clientSupported(classes, false));
- EXPECT_FALSE(pools.at(2)->clientSupported(classes, true));
- EXPECT_TRUE(pools.at(3)->clientSupported(classes, false));
- EXPECT_TRUE(pools.at(3)->clientSupported(classes, true));
-
- // Let's check if client belonging to gamma class is supported in pool[2]
- // and not supported in any other pool (except pool[3], which allows
- // everyone).
- classes.clear();
- classes.insert("gamma");
- EXPECT_FALSE(pools.at(0)->clientSupported(classes, false));
- EXPECT_FALSE(pools.at(0)->clientSupported(classes, true));
- EXPECT_FALSE(pools.at(1)->clientSupported(classes, false));
- EXPECT_FALSE(pools.at(1)->clientSupported(classes, true));
- EXPECT_FALSE(pools.at(2)->clientSupported(classes, false));
- EXPECT_TRUE(pools.at(2)->clientSupported(classes, true));
- EXPECT_TRUE(pools.at(3)->clientSupported(classes, false));
- EXPECT_TRUE(pools.at(3)->clientSupported(classes, true));
-
- // Let's check if client belonging to some other class (not mentioned in
- // the config) is supported only in pool[3], which allows everyone.
- classes.clear();
- classes.insert("delta");
- EXPECT_FALSE(pools.at(0)->clientSupported(classes, false));
- EXPECT_FALSE(pools.at(0)->clientSupported(classes, true));
- EXPECT_FALSE(pools.at(1)->clientSupported(classes, false));
- EXPECT_FALSE(pools.at(1)->clientSupported(classes, true));
- EXPECT_FALSE(pools.at(2)->clientSupported(classes, false));
- EXPECT_FALSE(pools.at(2)->clientSupported(classes, true));
- EXPECT_TRUE(pools.at(3)->clientSupported(classes, false));
- EXPECT_TRUE(pools.at(3)->clientSupported(classes, true));
-
- // Finally, let's check class-less client. He should be allowed only in
- // the last pool, which does not have any class restrictions.
- classes.clear();
- EXPECT_FALSE(pools.at(0)->clientSupported(classes, false));
- EXPECT_FALSE(pools.at(0)->clientSupported(classes, true));
- EXPECT_FALSE(pools.at(1)->clientSupported(classes, false));
- EXPECT_FALSE(pools.at(1)->clientSupported(classes, true));
- EXPECT_FALSE(pools.at(2)->clientSupported(classes, false));
- EXPECT_FALSE(pools.at(2)->clientSupported(classes, true));
- EXPECT_TRUE(pools.at(3)->clientSupported(classes, false));
- EXPECT_TRUE(pools.at(3)->clientSupported(classes, true));
-}
-
// This test checks the ability of the server to parse a configuration
// containing a full, valid dhcp-ddns (D2ClientConfig) entry.
TEST_F(Dhcp6ParserTest, d2ClientConfig) {
-// Copyright (C) 2012-2017 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2012-2018 Internet Systems Consortium, Inc. ("ISC")
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
isc::asiolink::IOAddress
AllocEngine::IterativeAllocator::pickAddress(const SubnetPtr& subnet,
const ClientClasses& client_classes,
- bool known_client,
const DuidPtr&,
const IOAddress&) {
PoolCollection::const_iterator first = pools.end();
PoolPtr first_pool;
for (it = pools.begin(); it != pools.end(); ++it) {
- if (!(*it)->clientSupported(client_classes, known_client)) {
+ if (!(*it)->clientSupported(client_classes)) {
continue;
}
if (first == pools.end()) {
// Trying next pool
if (retrying) {
for (; it != pools.end(); ++it) {
- if ((*it)->clientSupported(client_classes, known_client)) {
+ if ((*it)->clientSupported(client_classes)) {
break;
}
}
// Let's rewind to the beginning.
for (it = first; it != pools.end(); ++it) {
- if ((*it)->clientSupported(client_classes, known_client)) {
+ if ((*it)->clientSupported(client_classes)) {
(*it)->setLastAllocated((*it)->getFirstAddress());
(*it)->resetLastAllocated();
}
isc::asiolink::IOAddress
AllocEngine::HashedAllocator::pickAddress(const SubnetPtr&,
const ClientClasses&,
- bool known_client,
const DuidPtr&,
const IOAddress&) {
isc_throw(NotImplemented, "Hashed allocator is not implemented");
isc::asiolink::IOAddress
AllocEngine::RandomAllocator::pickAddress(const SubnetPtr&,
const ClientClasses&,
- bool known_client,
const DuidPtr&,
const IOAddress&) {
isc_throw(NotImplemented, "Random allocator is not implemented");
}
} else {
if (current_subnet->inPool(lease_type, address,
- ctx.query_->getClasses(),
- !ctx.hosts_.empty())) {
+ ctx.query_->getClasses())) {
return (true);
}
}
// This is equivalent of subnet->inPool(hint), but returns the pool
pool = boost::dynamic_pointer_cast<Pool6>
(subnet->getPool(ctx.currentIA().type_, ctx.query_->getClasses(),
- !ctx.hosts_.empty(), hint));
+ hint));
// check if the pool is allowed
- if (pool && !pool->clientSupported(ctx.query_->getClasses(),
- !ctx.hosts_.empty())) {
+ if (pool && !pool->clientSupported(ctx.query_->getClasses())) {
pool.reset();
}
// - we exhaust number of tries
uint64_t possible_attempts =
subnet->getPoolCapacity(ctx.currentIA().type_,
- ctx.query_->getClasses(),
- !ctx.hosts_.empty());
+ ctx.query_->getClasses());
// Try next subnet if there is no chance to get something
if (possible_attempts == 0) {
subnet = subnet->getNextSubnet(original_subnet);
IOAddress candidate = allocator->pickAddress(subnet,
ctx.query_->getClasses(),
- !ctx.hosts_.empty(),
ctx.duid_,
hint);
pool = boost::dynamic_pointer_cast<Pool6>(
subnet->getPool(ctx.currentIA().type_,
ctx.query_->getClasses(),
- !ctx.hosts_.empty(),
candidate));
if (pool) {
prefix_len = pool->getLength();
while (current_subnet) {
if (current_subnet->inPool(Lease::TYPE_V4, address,
- ctx.query_->getClasses(),
- !ctx.hosts_.empty())) {
+ ctx.query_->getClasses())) {
// We found a subnet that this address belongs to, so it
// seems that this subnet is the good candidate for allocation.
// Let's update the selected subnet.
uint64_t possible_attempts =
subnet->getPoolCapacity(Lease::TYPE_V4,
- ctx.query_->getClasses(),
- !ctx.hosts_.empty());
+ ctx.query_->getClasses());
uint64_t max_attempts = (attempts_ > 0 ? attempts_ : possible_attempts);
// Skip trying if there is no chance to get something
if (possible_attempts == 0) {
for (uint64_t i = 0; i < max_attempts; ++i) {
IOAddress candidate = allocator->pickAddress(subnet,
ctx.query_->getClasses(),
- !ctx.hosts_.empty(),
client_id,
ctx.requested_address_);
// If address is not reserved for another client, try to allocate it.
///
/// @param subnet next address will be returned from pool of that subnet
/// @param client_classes list of classes client belongs to
- /// @param known_client client has a reservation
/// @param duid Client's DUID
/// @param hint client's hint
///
virtual isc::asiolink::IOAddress
pickAddress(const SubnetPtr& subnet,
const ClientClasses& client_classes,
- bool known_client,
const DuidPtr& duid,
const isc::asiolink::IOAddress& hint) = 0;
///
/// @param subnet next address will be returned from pool of that subnet
/// @param client_classes list of classes client belongs to
- /// @param known_client client has a reservation
/// @param duid Client's DUID (ignored)
/// @param hint client's hint (ignored)
/// @return the next address
virtual isc::asiolink::IOAddress
pickAddress(const SubnetPtr& subnet,
const ClientClasses& client_classes,
- bool known_client,
const DuidPtr& duid,
const isc::asiolink::IOAddress& hint);
protected:
///
/// @param subnet an address will be picked from pool of that subnet
/// @param client_classes list of classes client belongs to
- /// @param known_client client has a reservation
/// @param duid Client's DUID
/// @param hint a hint (last address that was picked)
/// @return selected address
virtual isc::asiolink::IOAddress
pickAddress(const SubnetPtr& subnet,
const ClientClasses& client_classes,
- bool known_client,
const DuidPtr& duid,
const isc::asiolink::IOAddress& hint);
};
virtual isc::asiolink::IOAddress
pickAddress(const SubnetPtr& subnet,
const ClientClasses& client_classes,
- bool known_client,
const DuidPtr& duid,
const isc::asiolink::IOAddress& hint);
};
-// Copyright (C) 2013-2017 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2013-2018 Internet Systems Consortium, Inc. ("ISC")
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
pool->deferClientClass((*cclass)->stringValue());
}
}
-
- // Known-clients.
- ConstElementPtr known_clients = pool_structure->get("known-clients");
- if (known_clients) {
- string kc = known_clients->stringValue();
- if (kc == "only") {
- pool->setKnownClients(Pool::SERVE_KNOWN);
- } else if (kc == "never") {
- pool->setKnownClients(Pool::SERVE_UNKNOWN);
- } else
- isc_throw(DhcpConfigError, "invalid known-clients value: " << kc
- << " (" << known_clients->getPosition() << ")");
- }
}
//****************************** Pool4Parser *************************
client_class_ = client_class;
}
- ConstElementPtr known_clients = pd_pool_->get("known-clients");
- if (known_clients) {
- known_clients_ = known_clients;
- }
-
ConstElementPtr class_list = pd_pool_->get("eval-client-classes");
// Check the pool parameters. It will throw an exception if any
}
}
- if (known_clients_) {
- string kc = known_clients_->stringValue();
- if (kc == "only") {
- pool_->setKnownClients(Pool::SERVE_KNOWN);
- } else if (kc == "never") {
- pool_->setKnownClients(Pool::SERVE_UNKNOWN);
- } else
- isc_throw(isc::dhcp::DhcpConfigError,
- "invalid known-clients value: " << kc
- << " (" << known_clients_->getPosition() << ")");
- }
-
if (class_list) {
const std::vector<data::ElementPtr>& classes = class_list->listValue();
for (auto cclass = classes.cbegin();
-// Copyright (C) 2013-2017 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2013-2018 Internet Systems Consortium, Inc. ("ISC")
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
isc::data::ConstElementPtr user_context_;
isc::data::ConstElementPtr client_class_;
-
- isc::data::ConstElementPtr known_clients_;
};
/// @brief Parser for a list of prefix delegation pools.
-// Copyright (C) 2012-2017 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2012-2018 Internet Systems Consortium, Inc. ("ISC")
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
const isc::asiolink::IOAddress& last)
:id_(getNextID()), first_(first), last_(last), type_(type),
capacity_(0), cfg_option_(new CfgOption()), client_class_(""),
- known_clients_(SERVE_BOTH),
last_allocated_(first), last_allocated_valid_(false) {
}
return (first_.smallerEqual(addr) && addr.smallerEqual(last_));
}
-bool Pool::clientSupported(const ClientClasses& classes,
- bool known_client) const {
- bool match = false;
+bool Pool::clientSupported(const ClientClasses& classes) const {
if (client_class_.empty()) {
// There is no class defined for this pool, so we do
// support everyone.
- match = true;
+ return (true);
} else if (classes.contains(client_class_)) {
- match = true;
- }
-
- if (!match) {
- return (false);
- }
-
- switch (known_clients_) {
- case SERVE_BOTH:
return (true);
- case SERVE_KNOWN:
- return (known_client);
- case SERVE_UNKNOWN:
- return (!known_client);
- default:
- // Saninity check for an impossible condition
- isc_throw(BadValue, "Invalid value of known clients");
}
+ return (false);
}
void Pool::allowClientClass(const ClientClass& class_name) {
map->set("client-class", Element::create(cclass));
}
- // Set known-clients
- KnownClients kc = getKnownClients();
- if (kc != SERVE_BOTH) {
- map->set("known-clients",
- Element::create(kc == SERVE_KNOWN ? "only" : "never"));
- }
-
// Set eval-client-classes
const ClientClasses& classes = getOnDemandClasses();
if (!classes.empty()) {
-// Copyright (C) 2012-2017 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2012-2018 Internet Systems Consortium, Inc. ("ISC")
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
class Pool {
public:
- /// @brief Value of known clients
- typedef enum {
- SERVE_BOTH = 0, ///< the pool serves both known and unknown clients
- SERVE_KNOWN = 1, ///< the pool serves only known clients
- SERVE_UNKNOWN = 2 ///< the pool never serves known clients
- } KnownClients;
-
/// @note:
/// PoolType enum was removed. Please use Lease::Type instead
/// specified classes.
///
/// @param client_classes list of all classes the client belongs to
- /// @param known_client true if the client is known, i.e. has a
- /// reservation
/// @return true if client can be supported, false otherwise
- bool clientSupported(const ClientClasses& client_classes,
- bool known_client) const;
+ bool clientSupported(const ClientClasses& client_classes) const;
/// @brief Sets the supported class to class class_name
///
return (client_class_);
}
- /// @brief Returns the value of known clients
- KnownClients getKnownClients() const {
- return (known_clients_);
- }
-
- /// @brief Sets the value of known clients
- void setKnownClients(KnownClients known_clients) {
- known_clients_ = known_clients;
- }
-
/// @brief Adds class class_name to classes to be evaluated later
///
/// @param class_name client class to be evaluated later
/// @ref Network::client_class_
ClientClass client_class_;
- /// @brief Value of known clients
- KnownClients known_clients_;
-
/// @brief On demand classes
///
/// @ref isc::dhcp::Network::on_demand_classes
-// Copyright (C) 2012-2017 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2012-2018 Internet Systems Consortium, Inc. ("ISC")
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
uint64_t
Subnet::getPoolCapacity(Lease::Type type,
- const ClientClasses& client_classes,
- bool known_client) const {
+ const ClientClasses& client_classes) const {
switch (type) {
case Lease::TYPE_V4:
case Lease::TYPE_NA:
- return sumPoolCapacity(pools_, client_classes, known_client);
+ return sumPoolCapacity(pools_, client_classes);
case Lease::TYPE_TA:
- return sumPoolCapacity(pools_ta_, client_classes, known_client);
+ return sumPoolCapacity(pools_ta_, client_classes);
case Lease::TYPE_PD:
- return sumPoolCapacity(pools_pd_, client_classes, known_client);
+ return sumPoolCapacity(pools_pd_, client_classes);
default:
isc_throw(BadValue, "Unsupported pool type: "
<< static_cast<int>(type));
uint64_t
Subnet::sumPoolCapacity(const PoolCollection& pools,
- const ClientClasses& client_classes,
- bool known_client) const {
+ const ClientClasses& client_classes) const {
uint64_t sum = 0;
for (PoolCollection::const_iterator p = pools.begin(); p != pools.end(); ++p) {
- if (!(*p)->clientSupported(client_classes, known_client)) {
+ if (!(*p)->clientSupported(client_classes)) {
continue;
}
uint64_t x = (*p)->getCapacity();
const PoolPtr Subnet::getPool(Lease::Type type,
const ClientClasses& client_classes,
- bool known_client,
const isc::asiolink::IOAddress& hint) const {
// check if the type is valid (and throw if it isn't)
checkType(type);
if (ub != pools.begin()) {
--ub;
if ((*ub)->inRange(hint) &&
- (*ub)->clientSupported(client_classes, known_client)) {
+ (*ub)->clientSupported(client_classes)) {
candidate = *ub;
}
}
bool
Subnet::inPool(Lease::Type type,
const isc::asiolink::IOAddress& addr,
- const ClientClasses& client_classes,
- bool known_client) const {
+ const ClientClasses& client_classes) const {
// Let's start with checking if it even belongs to that subnet.
if ((type != Lease::TYPE_PD) && !inRange(addr)) {
for (PoolCollection::const_iterator pool = pools.begin();
pool != pools.end(); ++pool) {
- if (!(*pool)->clientSupported(client_classes, known_client)) {
+ if (!(*pool)->clientSupported(client_classes)) {
continue;
}
if ((*pool)->inRange(addr)) {
-// Copyright (C) 2012-2017 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2012-2018 Internet Systems Consortium, Inc. ("ISC")
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
/// @brief checks if the specified address is in allowed pools
///
- /// This takes also into account client classes and known client
+ /// This takes also into account client classes
///
/// @param type type of pools to iterate over
/// @param addr this address will be checked if it belongs to any pools in
/// that subnet
/// @param client_classes client class list which must be allowed
- /// @param known_client true if the client is known, i.e. has a reservation
/// @return true if the address is in any of the allowed pools
bool inPool(Lease::Type type,
const isc::asiolink::IOAddress& addr,
- const ClientClasses& client_classes,
- bool known_client) const;
+ const ClientClasses& client_classes) const;
/// @brief returns the last address that was tried from this subnet
///
/// @brief Returns a pool that specified address belongs to with classes
///
- /// Variant using only pools allowing given classes and known clients
+ /// Variant using only pools allowing given classes
///
/// @param type pool type that the pool is looked for
/// @param client_classes client class list which must be allowed
- /// @param known_client true if the client is known, i.e. has a reservation
/// @param addr address that the returned pool should cover (optional)
const PoolPtr getPool(Lease::Type type,
const ClientClasses& client_classes,
- bool known_client,
const isc::asiolink::IOAddress& addr) const;
/// @brief Returns a pool without any address specified
uint64_t getPoolCapacity(Lease::Type type) const;
/// @brief Returns the number of possible leases for specified lease type
- /// allowed for a client which belongs to classes and matches known
- /// clients constraint.
+ /// allowed for a client which belongs to classes.
///
/// @param type type of the lease
/// @param client_classes List of classes the client belongs to.
- /// @param known_client true if the client is known, i.e. has a reservation
uint64_t getPoolCapacity(Lease::Type type,
- const ClientClasses& client_classes,
- bool known_client) const;
+ const ClientClasses& client_classes) const;
/// @brief Returns textual representation of the subnet (e.g.
/// "2001:db8::/64")
/// @brief returns a sum of possible leases in all pools allowing classes
/// @param pools list of pools
/// @param client_classes list of classes
- /// @param known_client true if the client is known, i.e. has a reservation
/// @return sum of possible/allowed leases
uint64_t sumPoolCapacity(const PoolCollection& pools,
- const ClientClasses& client_classes,
- bool known_client) const;
+ const ClientClasses& client_classes) const;
/// @brief Checks if the specified pool overlaps with an existing pool.
///
-// Copyright (C) 2015-2017 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2015-2018 Internet Systems Consortium, Inc. ("ISC")
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
alloc(new NakedAllocEngine::IterativeAllocator(Lease::TYPE_V4));
for (int i = 0; i < 1000; ++i) {
- IOAddress candidate = alloc->pickAddress(subnet_, cc_,
- known_client_, clientid_,
+ IOAddress candidate = alloc->pickAddress(subnet_, cc_, clientid_,
IOAddress("0.0.0.0"));
EXPECT_TRUE(subnet_->inPool(Lease::TYPE_V4, candidate));
}
cc_.insert("bar");
for (int i = 0; i < 1000; ++i) {
- IOAddress candidate = alloc->pickAddress(subnet_, cc_,
- known_client_, clientid_,
+ IOAddress candidate = alloc->pickAddress(subnet_, cc_, clientid_,
IOAddress("0.0.0.0"));
EXPECT_TRUE(subnet_->inPool(Lease::TYPE_V4, candidate));
- EXPECT_TRUE(subnet_->inPool(Lease::TYPE_V4, candidate, cc_, known_client_));
- }
-}
-
-// This test verifies that the allocator picks addresses that belong to the
-// pool using unknown clients
-TEST_F(AllocEngine4Test, IterativeAllocator_unknown) {
- boost::scoped_ptr<NakedAllocEngine::Allocator>
- alloc(new NakedAllocEngine::IterativeAllocator(Lease::TYPE_V4));
-
- // Restrict pool_ to known clients. Add a second pool for unknown clients.
- pool_->setKnownClients(Pool::SERVE_KNOWN);
- Pool4Ptr pool(new Pool4(IOAddress("192.0.2.200"),
- IOAddress("192.0.2.209")));
- pool->setKnownClients(Pool::SERVE_UNKNOWN);
- subnet_->addPool(pool);
-
- // Clients are unknown
- known_client_ = false;
-
- for (int i = 0; i < 1000; ++i) {
- IOAddress candidate = alloc->pickAddress(subnet_, cc_,
- known_client_, clientid_,
- IOAddress("0.0.0.0"));
- EXPECT_TRUE(subnet_->inPool(Lease::TYPE_V4, candidate));
- EXPECT_TRUE(subnet_->inPool(Lease::TYPE_V4, candidate, cc_, known_client_));
- EXPECT_FALSE(subnet_->inPool(Lease::TYPE_V4, candidate, cc_, !known_client_));
+ EXPECT_TRUE(subnet_->inPool(Lease::TYPE_V4, candidate, cc_));
}
}
std::set<IOAddress> generated_addrs;
int cnt = 0;
while (++cnt) {
- IOAddress candidate = alloc.pickAddress(subnet_, cc_, known_client_, clientid_, IOAddress("0.0.0.0"));
+ IOAddress candidate = alloc.pickAddress(subnet_, cc_, clientid_, IOAddress("0.0.0.0"));
EXPECT_TRUE(subnet_->inPool(Lease::TYPE_V4, candidate));
// One way to easily verify that the iterative allocator really works is
EXPECT_EQ("192.0.2.17", lease->addr_.toText());
}
-// This test verifies that the server can offer an address from a
-// different subnet than orginally selected, when the address pool in
-// the first subnet requires host reservations.
-TEST_F(SharedNetworkAlloc4Test, discoverSharedNetworkPoolKnown) {
-
- // Try to offer address from subnet1. There is one address available
- // so it should be offerred.
- AllocEngine::ClientContext4
- ctx(subnet1_, ClientIdPtr(), hwaddr_, IOAddress::IPV4_ZERO_ADDRESS(),
- false, false, "host.example.com.", true);
- ctx.query_.reset(new Pkt4(DHCPDISCOVER, 1234));
- Lease4Ptr lease = engine_.allocateLease4(ctx);
- ASSERT_TRUE(lease);
- EXPECT_TRUE(subnet1_->inPool(Lease::TYPE_V4, lease->addr_));
-
- // Apply restrictions on the pool1. This should be only assigned
- // to clients which have a reservation.
- pool1_->setKnownClients(Pool::SERVE_KNOWN);
-
- // The allocation engine should determine that the pool1 is not
- // available for the client without a reservation.
- // Instead, it should offer an address from subnet2 that belongs
- // to the same shared network.
- ctx.subnet_ = subnet1_;
- lease = engine_.allocateLease4(ctx);
- ASSERT_TRUE(lease);
- EXPECT_TRUE(subnet2_->inPool(Lease::TYPE_V4, lease->addr_));
-
- // Add a host reservation and try again. This time, we should
- // offer an address from the pool1.
- HostPtr host(new Host(&hwaddr_->hwaddr_[0], hwaddr_->hwaddr_.size(),
- Host::IDENT_HWADDR, subnet1_->getID(),
- SubnetID(0), IOAddress::IPV4_ZERO_ADDRESS(), "foo"));
- CfgMgr::instance().getStagingCfg()->getCfgHosts()->add(host);
- CfgMgr::instance().commit();
- AllocEngine::findReservation(ctx);
-
- ctx.subnet_ = subnet1_;
- lease = engine_.allocateLease4(ctx);
- ASSERT_TRUE(lease);
- EXPECT_EQ("192.0.2.17", lease->addr_.toText());
-}
-
// Test that reservations within shared network take precedence over the
// existing leases regardless in which subnet belonging to a shared network
// reservations belong.
EXPECT_TRUE(subnet2_->inPool(Lease::TYPE_V4, lease->addr_));
}
-// This test verifies that the server can assign an address from a
-// different subnet than orginally selected, when the address pool in
-// the first subnet requires host reservations.
-TEST_F(SharedNetworkAlloc4Test, requestSharedNetworkPoolKnown) {
- // Try to offer address from subnet1. There is one address available
- // so it should be offerred.
- AllocEngine::ClientContext4
- ctx(subnet1_, ClientIdPtr(), hwaddr_, IOAddress::IPV4_ZERO_ADDRESS(),
- false, false, "host.example.com.", false);
- ctx.query_.reset(new Pkt4(DHCPREQUEST, 1234));
- Lease4Ptr lease = engine_.allocateLease4(ctx);
- ASSERT_TRUE(lease);
- EXPECT_TRUE(subnet1_->inPool(Lease::TYPE_V4, lease->addr_));
-
- // Remove the lease so as we can start over.
- LeaseMgrFactory::instance().deleteLease(lease->addr_);
-
- // Apply restrictions on the pool1. This should be only assigned
- // to clients which have a reservation.
- pool1_->setKnownClients(Pool::SERVE_KNOWN);
-
- // The allocation engine should determine that the pool1 is not
- // available for the client without a reservation.
- // Instead, it should assign an address from subnet2 that belongs
- // to the same shared network.
- ctx.subnet_ = subnet1_;
- lease = engine_.allocateLease4(ctx);
- ASSERT_TRUE(lease);
- EXPECT_TRUE(subnet2_->inPool(Lease::TYPE_V4, lease->addr_));
-
- // Remove the lease so as we can start over.
- LeaseMgrFactory::instance().deleteLease(lease->addr_);
-
- // Add a host reservation and try again. This time, we should
- // offer an address from the pool1.
- HostPtr host(new Host(&hwaddr_->hwaddr_[0], hwaddr_->hwaddr_.size(),
- Host::IDENT_HWADDR, subnet1_->getID(),
- SubnetID(0), IOAddress::IPV4_ZERO_ADDRESS(), "foo"));
- CfgMgr::instance().getStagingCfg()->getCfgHosts()->add(host);
- CfgMgr::instance().commit();
- AllocEngine::findReservation(ctx);
-
- ctx.subnet_ = subnet1_;
- lease = engine_.allocateLease4(ctx);
- ASSERT_TRUE(lease);
- EXPECT_TRUE(subnet1_->inPool(Lease::TYPE_V4, lease->addr_));
-
- // Let's now remove the client host reservation and try
- // to renew the address. The engine should determine that the
- // client doesn't have access to the pool1 anymore and
- // assign an address from unrestricted pool.
-#if 0
- CfgMgr::instance().getStagingCfg()->getCfgHosts()->del4(SubnetID(0),
- Host::IDENT_HWADDR,
- &hwaddr_->hwaddr_[0],
- hwaddr_->hwaddr_.size());
- CfgMgr::instance().commit();
- AllocEngine::findReservation(ctx);
-#else
- // del4 is not always implemented
- ctx.hosts_.clear();
-#endif
- ctx.query_.reset(new Pkt4(DHCPREQUEST, 1234));
- ctx.subnet_ = subnet1_;
- lease = engine_.allocateLease4(ctx);
- ASSERT_TRUE(lease);
- EXPECT_TRUE(subnet2_->inPool(Lease::TYPE_V4, lease->addr_));
-}
-
// Test that reservations within shared network take precedence over the
// existing leases regardless in which subnet belonging to a shared network
// reservations belong (DHCPREQUEST case).
-// Copyright (C) 2015-2017 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2015-2018 Internet Systems Consortium, Inc. ("ISC")
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
alloc(new NakedAllocEngine::IterativeAllocator(Lease::TYPE_NA));
for (int i = 0; i < 1000; ++i) {
- IOAddress candidate = alloc->pickAddress(subnet_, cc_, known_client_,
+ IOAddress candidate = alloc->pickAddress(subnet_, cc_,
duid_, IOAddress("::"));
EXPECT_TRUE(subnet_->inPool(Lease::TYPE_NA, candidate));
}
cc_.insert("bar");
for (int i = 0; i < 1000; ++i) {
- IOAddress candidate = alloc->pickAddress(subnet_, cc_, known_client_,
+ IOAddress candidate = alloc->pickAddress(subnet_, cc_,
duid_, IOAddress("::"));
EXPECT_TRUE(subnet_->inPool(Lease::TYPE_NA, candidate));
- EXPECT_TRUE(subnet_->inPool(Lease::TYPE_NA, candidate, cc_, known_client_));
- }
-}
-
-// This test verifies that the allocator picks addresses that belong to the
-// pool not requiring reservations
-TEST_F(AllocEngine6Test, IterativeAllocator_unknown) {
- boost::scoped_ptr<NakedAllocEngine::Allocator>
- alloc(new NakedAllocEngine::IterativeAllocator(Lease::TYPE_NA));
-
- // Restrict pool_ to known clients. Add a second pool for unknown clients.
- pool_->setKnownClients(Pool::SERVE_KNOWN);
- Pool6Ptr pool(new Pool6(Lease::TYPE_NA, IOAddress("2001:db8:1::100"),
- IOAddress("2001:db8:1::109")));
- pool->setKnownClients(Pool::SERVE_UNKNOWN);
- subnet_->addPool(pool);
-
- // Clients are unknown
- known_client_ = false;
-
- for (int i = 0; i < 1000; ++i) {
- IOAddress candidate = alloc->pickAddress(subnet_, cc_, known_client_,
- duid_, IOAddress("::"));
- EXPECT_TRUE(subnet_->inPool(Lease::TYPE_NA, candidate));
- EXPECT_TRUE(subnet_->inPool(Lease::TYPE_NA, candidate, cc_, known_client_));
- EXPECT_FALSE(subnet_->inPool(Lease::TYPE_NA, candidate, cc_, !known_client_));
}
}
// Let's check the first pool (5 addresses here)
EXPECT_EQ("2001:db8:1::1",
- alloc.pickAddress(subnet_, cc_, known_client_, duid_,
- IOAddress("::")).toText());
+ alloc.pickAddress(subnet_, cc_, duid_, IOAddress("::")).toText());
EXPECT_EQ("2001:db8:1::2",
- alloc.pickAddress(subnet_, cc_, known_client_, duid_,
- IOAddress("::")).toText());
+ alloc.pickAddress(subnet_, cc_, duid_, IOAddress("::")).toText());
EXPECT_EQ("2001:db8:1::3",
- alloc.pickAddress(subnet_, cc_, known_client_, duid_,
- IOAddress("::")).toText());
+ alloc.pickAddress(subnet_, cc_, duid_, IOAddress("::")).toText());
EXPECT_EQ("2001:db8:1::4",
- alloc.pickAddress(subnet_, cc_, known_client_, duid_,
- IOAddress("::")).toText());
+ alloc.pickAddress(subnet_, cc_, duid_, IOAddress("::")).toText());
EXPECT_EQ("2001:db8:1::5",
- alloc.pickAddress(subnet_, cc_, known_client_, duid_,
- IOAddress("::")).toText());
+ alloc.pickAddress(subnet_, cc_, duid_, IOAddress("::")).toText());
// The second pool is easy - only one address here
EXPECT_EQ("2001:db8:1::100",
- alloc.pickAddress(subnet_, cc_, known_client_, duid_,
- IOAddress("::")).toText());
+ alloc.pickAddress(subnet_, cc_, duid_, IOAddress("::")).toText());
// This is the third and last pool, with 2 addresses in it
EXPECT_EQ("2001:db8:1::105",
- alloc.pickAddress(subnet_, cc_, known_client_, duid_,
- IOAddress("::")).toText());
+ alloc.pickAddress(subnet_, cc_, duid_, IOAddress("::")).toText());
EXPECT_EQ("2001:db8:1::106",
- alloc.pickAddress(subnet_, cc_, known_client_, duid_,
- IOAddress("::")).toText());
+ alloc.pickAddress(subnet_, cc_, duid_, IOAddress("::")).toText());
// We iterated over all addresses and reached to the end of the last pool.
// Let's wrap around and start from the beginning
EXPECT_EQ("2001:db8:1::1",
- alloc.pickAddress(subnet_, cc_, known_client_, duid_,
- IOAddress("::")).toText());
+ alloc.pickAddress(subnet_, cc_, duid_, IOAddress("::")).toText());
EXPECT_EQ("2001:db8:1::2",
- alloc.pickAddress(subnet_, cc_, known_client_, duid_,
- IOAddress("::")).toText());
+ alloc.pickAddress(subnet_, cc_, duid_, IOAddress("::")).toText());
}
TEST_F(AllocEngine6Test, IterativeAllocatorAddrStepInClass) {
// Let's check the first pool (5 addresses here)
EXPECT_EQ("2001:db8:1::1",
- alloc.pickAddress(subnet_, cc_, known_client_, duid_,
- IOAddress("::")).toText());
+ alloc.pickAddress(subnet_, cc_, duid_, IOAddress("::")).toText());
EXPECT_EQ("2001:db8:1::2",
- alloc.pickAddress(subnet_, cc_, known_client_, duid_,
- IOAddress("::")).toText());
+ alloc.pickAddress(subnet_, cc_, duid_, IOAddress("::")).toText());
EXPECT_EQ("2001:db8:1::3",
- alloc.pickAddress(subnet_, cc_, known_client_, duid_,
- IOAddress("::")).toText());
+ alloc.pickAddress(subnet_, cc_, duid_, IOAddress("::")).toText());
EXPECT_EQ("2001:db8:1::4",
- alloc.pickAddress(subnet_, cc_, known_client_, duid_,
- IOAddress("::")).toText());
+ alloc.pickAddress(subnet_, cc_, duid_, IOAddress("::")).toText());
EXPECT_EQ("2001:db8:1::5",
- alloc.pickAddress(subnet_, cc_, known_client_, duid_,
- IOAddress("::")).toText());
+ alloc.pickAddress(subnet_, cc_, duid_, IOAddress("::")).toText());
// The second pool is easy - only one address here
EXPECT_EQ("2001:db8:1::100",
- alloc.pickAddress(subnet_, cc_, known_client_, duid_,
- IOAddress("::")).toText());
+ alloc.pickAddress(subnet_, cc_, duid_, IOAddress("::")).toText());
// This is the third and last pool, with 2 addresses in it
EXPECT_EQ("2001:db8:1::105",
- alloc.pickAddress(subnet_, cc_, known_client_, duid_,
- IOAddress("::")).toText());
+ alloc.pickAddress(subnet_, cc_, duid_, IOAddress("::")).toText());
EXPECT_EQ("2001:db8:1::106",
- alloc.pickAddress(subnet_, cc_, known_client_, duid_,
- IOAddress("::")).toText());
+ alloc.pickAddress(subnet_, cc_, duid_, IOAddress("::")).toText());
// We iterated over all addresses and reached to the end of the last pool.
// Let's wrap around and start from the beginning
EXPECT_EQ("2001:db8:1::1",
- alloc.pickAddress(subnet_, cc_, known_client_, duid_,
- IOAddress("::")).toText());
+ alloc.pickAddress(subnet_, cc_, duid_, IOAddress("::")).toText());
EXPECT_EQ("2001:db8:1::2",
- alloc.pickAddress(subnet_, cc_, known_client_, duid_,
- IOAddress("::")).toText());
+ alloc.pickAddress(subnet_, cc_, duid_, IOAddress("::")).toText());
}
TEST_F(AllocEngine6Test, IterativeAllocatorAddrStepOutClass) {
// Let's check the first pool (5 addresses here)
EXPECT_EQ("2001:db8:1::1",
- alloc.pickAddress(subnet_, cc_, known_client_, duid_,
- IOAddress("::")).toText());
+ alloc.pickAddress(subnet_, cc_, duid_, IOAddress("::")).toText());
EXPECT_EQ("2001:db8:1::2",
- alloc.pickAddress(subnet_, cc_, known_client_, duid_,
- IOAddress("::")).toText());
+ alloc.pickAddress(subnet_, cc_, duid_, IOAddress("::")).toText());
EXPECT_EQ("2001:db8:1::3",
- alloc.pickAddress(subnet_, cc_, known_client_, duid_,
- IOAddress("::")).toText());
+ alloc.pickAddress(subnet_, cc_, duid_, IOAddress("::")).toText());
EXPECT_EQ("2001:db8:1::4",
- alloc.pickAddress(subnet_, cc_, known_client_, duid_,
- IOAddress("::")).toText());
+ alloc.pickAddress(subnet_, cc_, duid_, IOAddress("::")).toText());
EXPECT_EQ("2001:db8:1::5",
- alloc.pickAddress(subnet_, cc_, known_client_, duid_,
- IOAddress("::")).toText());
+ alloc.pickAddress(subnet_, cc_, duid_, IOAddress("::")).toText());
// The second pool is skipped
// This is the third and last pool, with 2 addresses in it
EXPECT_EQ("2001:db8:1::105",
- alloc.pickAddress(subnet_, cc_, known_client_, duid_,
- IOAddress("::")).toText());
+ alloc.pickAddress(subnet_, cc_, duid_, IOAddress("::")).toText());
EXPECT_EQ("2001:db8:1::106",
- alloc.pickAddress(subnet_, cc_, known_client_, duid_,
- IOAddress("::")).toText());
+ alloc.pickAddress(subnet_, cc_, duid_, IOAddress("::")).toText());
// We iterated over all addresses and reached to the end of the last pool.
// Let's wrap around and start from the beginning
EXPECT_EQ("2001:db8:1::1",
- alloc.pickAddress(subnet_, cc_, known_client_, duid_,
- IOAddress("::")).toText());
+ alloc.pickAddress(subnet_, cc_, duid_, IOAddress("::")).toText());
EXPECT_EQ("2001:db8:1::2",
- alloc.pickAddress(subnet_, cc_, known_client_, duid_,
- IOAddress("::")).toText());
-}
-
-TEST_F(AllocEngine6Test, IterativeAllocatorAddrStepKnown) {
- NakedAllocEngine::NakedIterativeAllocator alloc(Lease::TYPE_NA);
-
- subnet_->delPools(Lease::TYPE_NA); // Get rid of default pool
-
- Pool6Ptr pool1(new Pool6(Lease::TYPE_NA, IOAddress("2001:db8:1::1"),
- IOAddress("2001:db8:1::5")));
- Pool6Ptr pool2(new Pool6(Lease::TYPE_NA, IOAddress("2001:db8:1::100"),
- IOAddress("2001:db8:1::100")));
- Pool6Ptr pool3(new Pool6(Lease::TYPE_NA, IOAddress("2001:db8:1::105"),
- IOAddress("2001:db8:1::106")));
- // The pool1 serves everybody, pool2 known clients, pool3 unknown clients.
- // Set pool1 and pool3 but not pool2 in foo class
- pool1->setKnownClients(Pool::SERVE_BOTH);
- pool2->setKnownClients(Pool::SERVE_KNOWN);
- pool3->setKnownClients(Pool::SERVE_UNKNOWN);
- subnet_->addPool(pool1);
- subnet_->addPool(pool2);
- subnet_->addPool(pool3);
-
- // Clients have no reservation
- known_client_ = false;
-
- // Let's check the first pool (5 addresses here)
- EXPECT_EQ("2001:db8:1::1",
- alloc.pickAddress(subnet_, cc_, known_client_, duid_,
- IOAddress("::")).toText());
- EXPECT_EQ("2001:db8:1::2",
- alloc.pickAddress(subnet_, cc_, known_client_, duid_,
- IOAddress("::")).toText());
- EXPECT_EQ("2001:db8:1::3",
- alloc.pickAddress(subnet_, cc_, known_client_, duid_,
- IOAddress("::")).toText());
- EXPECT_EQ("2001:db8:1::4",
- alloc.pickAddress(subnet_, cc_, known_client_, duid_,
- IOAddress("::")).toText());
- EXPECT_EQ("2001:db8:1::5",
- alloc.pickAddress(subnet_, cc_, known_client_, duid_,
- IOAddress("::")).toText());
-
- // The second pool is skipped
-
- // This is the third and last pool, with 2 addresses in it
- EXPECT_EQ("2001:db8:1::105",
- alloc.pickAddress(subnet_, cc_, known_client_, duid_,
- IOAddress("::")).toText());
- EXPECT_EQ("2001:db8:1::106",
- alloc.pickAddress(subnet_, cc_, known_client_, duid_,
- IOAddress("::")).toText());
-
- // We iterated over all addresses and reached to the end of the last pool.
- // Let's wrap around and start from the beginning
- EXPECT_EQ("2001:db8:1::1",
- alloc.pickAddress(subnet_, cc_, known_client_, duid_,
- IOAddress("::")).toText());
- EXPECT_EQ("2001:db8:1::2",
- alloc.pickAddress(subnet_, cc_, known_client_, duid_,
- IOAddress("::")).toText());
+ alloc.pickAddress(subnet_, cc_, duid_, IOAddress("::")).toText());
}
TEST_F(AllocEngine6Test, IterativeAllocatorPrefixStep) {
// First pool check (Let's check over all 16 leases)
EXPECT_EQ("2001:db8::",
- alloc.pickAddress(subnet_, cc_, known_client_, duid_,
- IOAddress("::")).toText());
+ alloc.pickAddress(subnet_, cc_, duid_, IOAddress("::")).toText());
EXPECT_EQ("2001:db8:0:10::",
- alloc.pickAddress(subnet_, cc_, known_client_, duid_,
- IOAddress("::")).toText());
+ alloc.pickAddress(subnet_, cc_, duid_, IOAddress("::")).toText());
EXPECT_EQ("2001:db8:0:20::",
- alloc.pickAddress(subnet_, cc_, known_client_, duid_,
- IOAddress("::")).toText());
+ alloc.pickAddress(subnet_, cc_, duid_, IOAddress("::")).toText());
EXPECT_EQ("2001:db8:0:30::",
- alloc.pickAddress(subnet_, cc_, known_client_, duid_,
- IOAddress("::")).toText());
+ alloc.pickAddress(subnet_, cc_, duid_, IOAddress("::")).toText());
EXPECT_EQ("2001:db8:0:40::",
- alloc.pickAddress(subnet_, cc_, known_client_, duid_,
- IOAddress("::")).toText());
+ alloc.pickAddress(subnet_, cc_, duid_, IOAddress("::")).toText());
EXPECT_EQ("2001:db8:0:50::",
- alloc.pickAddress(subnet_, cc_, known_client_, duid_,
- IOAddress("::")).toText());
+ alloc.pickAddress(subnet_, cc_, duid_, IOAddress("::")).toText());
EXPECT_EQ("2001:db8:0:60::",
- alloc.pickAddress(subnet_, cc_, known_client_, duid_,
- IOAddress("::")).toText());
+ alloc.pickAddress(subnet_, cc_, duid_, IOAddress("::")).toText());
EXPECT_EQ("2001:db8:0:70::",
- alloc.pickAddress(subnet_, cc_, known_client_, duid_,
- IOAddress("::")).toText());
+ alloc.pickAddress(subnet_, cc_, duid_, IOAddress("::")).toText());
EXPECT_EQ("2001:db8:0:80::",
- alloc.pickAddress(subnet_, cc_, known_client_, duid_,
- IOAddress("::")).toText());
+ alloc.pickAddress(subnet_, cc_, duid_, IOAddress("::")).toText());
EXPECT_EQ("2001:db8:0:90::",
- alloc.pickAddress(subnet_, cc_, known_client_, duid_,
- IOAddress("::")).toText());
+ alloc.pickAddress(subnet_, cc_, duid_, IOAddress("::")).toText());
EXPECT_EQ("2001:db8:0:a0::",
- alloc.pickAddress(subnet_, cc_, known_client_, duid_,
- IOAddress("::")).toText());
+ alloc.pickAddress(subnet_, cc_, duid_, IOAddress("::")).toText());
EXPECT_EQ("2001:db8:0:b0::",
- alloc.pickAddress(subnet_, cc_, known_client_, duid_,
- IOAddress("::")).toText());
+ alloc.pickAddress(subnet_, cc_, duid_, IOAddress("::")).toText());
EXPECT_EQ("2001:db8:0:c0::",
- alloc.pickAddress(subnet_, cc_, known_client_, duid_,
- IOAddress("::")).toText());
+ alloc.pickAddress(subnet_, cc_, duid_, IOAddress("::")).toText());
EXPECT_EQ("2001:db8:0:d0::",
- alloc.pickAddress(subnet_, cc_, known_client_, duid_,
- IOAddress("::")).toText());
+ alloc.pickAddress(subnet_, cc_, duid_, IOAddress("::")).toText());
EXPECT_EQ("2001:db8:0:e0::",
- alloc.pickAddress(subnet_, cc_, known_client_, duid_,
- IOAddress("::")).toText());
+ alloc.pickAddress(subnet_, cc_, duid_, IOAddress("::")).toText());
EXPECT_EQ("2001:db8:0:f0::",
- alloc.pickAddress(subnet_, cc_, known_client_, duid_,
- IOAddress("::")).toText());
+ alloc.pickAddress(subnet_, cc_, duid_, IOAddress("::")).toText());
// Second pool (just one lease here)
EXPECT_EQ("2001:db8:1::",
- alloc.pickAddress(subnet_, cc_, known_client_, duid_,
- IOAddress("::")).toText());
+ alloc.pickAddress(subnet_, cc_, duid_, IOAddress("::")).toText());
// Third pool (256 leases, let's check first and last explicitly and the
// rest over in a pool
EXPECT_EQ("2001:db8:2::",
- alloc.pickAddress(subnet_, cc_, known_client_, duid_,
- IOAddress("::")).toText());
+ alloc.pickAddress(subnet_, cc_, duid_, IOAddress("::")).toText());
for (int i = 1; i < 255; i++) {
stringstream exp;
exp << "2001:db8:2:" << hex << i << dec << "::";
EXPECT_EQ(exp.str(),
- alloc.pickAddress(subnet_, cc_, known_client_, duid_,
- IOAddress("::")).toText());
+ alloc.pickAddress(subnet_, cc_, duid_, IOAddress("::")).toText());
}
EXPECT_EQ("2001:db8:2:ff::",
- alloc.pickAddress(subnet_, cc_, known_client_, duid_,
- IOAddress("::")).toText());
+ alloc.pickAddress(subnet_, cc_, duid_, IOAddress("::")).toText());
// Ok, we've iterated over all prefixes in all pools. We now wrap around.
// We're looping over now (iterating over first pool again)
EXPECT_EQ("2001:db8::",
- alloc.pickAddress(subnet_, cc_, known_client_, duid_,
- IOAddress("::")).toText());
+ alloc.pickAddress(subnet_, cc_, duid_, IOAddress("::")).toText());
EXPECT_EQ("2001:db8:0:10::",
- alloc.pickAddress(subnet_, cc_, known_client_, duid_,
- IOAddress("::")).toText());
+ alloc.pickAddress(subnet_, cc_, duid_, IOAddress("::")).toText());
}
TEST_F(AllocEngine6Test, IterativeAllocatorPrefixStepInClass) {
// First pool check (Let's check over all 16 leases)
EXPECT_EQ("2001:db8::",
- alloc.pickAddress(subnet_, cc_, known_client_, duid_,
- IOAddress("::")).toText());
+ alloc.pickAddress(subnet_, cc_, duid_, IOAddress("::")).toText());
EXPECT_EQ("2001:db8:0:10::",
- alloc.pickAddress(subnet_, cc_, known_client_, duid_,
- IOAddress("::")).toText());
+ alloc.pickAddress(subnet_, cc_, duid_, IOAddress("::")).toText());
EXPECT_EQ("2001:db8:0:20::",
- alloc.pickAddress(subnet_, cc_, known_client_, duid_,
- IOAddress("::")).toText());
+ alloc.pickAddress(subnet_, cc_, duid_, IOAddress("::")).toText());
EXPECT_EQ("2001:db8:0:30::",
- alloc.pickAddress(subnet_, cc_, known_client_, duid_,
- IOAddress("::")).toText());
+ alloc.pickAddress(subnet_, cc_, duid_, IOAddress("::")).toText());
EXPECT_EQ("2001:db8:0:40::",
- alloc.pickAddress(subnet_, cc_, known_client_, duid_,
- IOAddress("::")).toText());
+ alloc.pickAddress(subnet_, cc_, duid_, IOAddress("::")).toText());
EXPECT_EQ("2001:db8:0:50::",
- alloc.pickAddress(subnet_, cc_, known_client_, duid_,
- IOAddress("::")).toText());
+ alloc.pickAddress(subnet_, cc_, duid_, IOAddress("::")).toText());
EXPECT_EQ("2001:db8:0:60::",
- alloc.pickAddress(subnet_, cc_, known_client_, duid_,
- IOAddress("::")).toText());
+ alloc.pickAddress(subnet_, cc_, duid_, IOAddress("::")).toText());
EXPECT_EQ("2001:db8:0:70::",
- alloc.pickAddress(subnet_, cc_, known_client_, duid_,
- IOAddress("::")).toText());
+ alloc.pickAddress(subnet_, cc_, duid_, IOAddress("::")).toText());
EXPECT_EQ("2001:db8:0:80::",
- alloc.pickAddress(subnet_, cc_, known_client_, duid_,
- IOAddress("::")).toText());
+ alloc.pickAddress(subnet_, cc_, duid_, IOAddress("::")).toText());
EXPECT_EQ("2001:db8:0:90::",
- alloc.pickAddress(subnet_, cc_, known_client_, duid_,
- IOAddress("::")).toText());
+ alloc.pickAddress(subnet_, cc_, duid_, IOAddress("::")).toText());
EXPECT_EQ("2001:db8:0:a0::",
- alloc.pickAddress(subnet_, cc_, known_client_, duid_,
- IOAddress("::")).toText());
+ alloc.pickAddress(subnet_, cc_, duid_, IOAddress("::")).toText());
EXPECT_EQ("2001:db8:0:b0::",
- alloc.pickAddress(subnet_, cc_, known_client_, duid_,
- IOAddress("::")).toText());
+ alloc.pickAddress(subnet_, cc_, duid_, IOAddress("::")).toText());
EXPECT_EQ("2001:db8:0:c0::",
- alloc.pickAddress(subnet_, cc_, known_client_, duid_,
- IOAddress("::")).toText());
+ alloc.pickAddress(subnet_, cc_, duid_, IOAddress("::")).toText());
EXPECT_EQ("2001:db8:0:d0::",
- alloc.pickAddress(subnet_, cc_, known_client_, duid_,
- IOAddress("::")).toText());
+ alloc.pickAddress(subnet_, cc_, duid_, IOAddress("::")).toText());
EXPECT_EQ("2001:db8:0:e0::",
- alloc.pickAddress(subnet_, cc_, known_client_, duid_,
- IOAddress("::")).toText());
+ alloc.pickAddress(subnet_, cc_, duid_, IOAddress("::")).toText());
EXPECT_EQ("2001:db8:0:f0::",
- alloc.pickAddress(subnet_, cc_, known_client_, duid_,
- IOAddress("::")).toText());
+ alloc.pickAddress(subnet_, cc_, duid_, IOAddress("::")).toText());
// Second pool (just one lease here)
EXPECT_EQ("2001:db8:1::",
- alloc.pickAddress(subnet_, cc_, known_client_, duid_,
- IOAddress("::")).toText());
+ alloc.pickAddress(subnet_, cc_, duid_, IOAddress("::")).toText());
// Third pool (256 leases, let's check first and last explicitly and the
// rest over in a pool
EXPECT_EQ("2001:db8:2::",
- alloc.pickAddress(subnet_, cc_, known_client_, duid_,
- IOAddress("::")).toText());
+ alloc.pickAddress(subnet_, cc_, duid_, IOAddress("::")).toText());
for (int i = 1; i < 255; i++) {
stringstream exp;
exp << "2001:db8:2:" << hex << i << dec << "::";
EXPECT_EQ(exp.str(),
- alloc.pickAddress(subnet_, cc_, known_client_, duid_,
- IOAddress("::")).toText());
+ alloc.pickAddress(subnet_, cc_, duid_, IOAddress("::")).toText());
}
EXPECT_EQ("2001:db8:2:ff::",
- alloc.pickAddress(subnet_, cc_, known_client_, duid_,
- IOAddress("::")).toText());
+ alloc.pickAddress(subnet_, cc_, duid_, IOAddress("::")).toText());
// Ok, we've iterated over all prefixes in all pools. We now wrap around.
// We're looping over now (iterating over first pool again)
EXPECT_EQ("2001:db8::",
- alloc.pickAddress(subnet_, cc_, known_client_, duid_,
- IOAddress("::")).toText());
+ alloc.pickAddress(subnet_, cc_, duid_, IOAddress("::")).toText());
EXPECT_EQ("2001:db8:0:10::",
- alloc.pickAddress(subnet_, cc_, known_client_, duid_,
- IOAddress("::")).toText());
+ alloc.pickAddress(subnet_, cc_, duid_, IOAddress("::")).toText());
}
TEST_F(AllocEngine6Test, IterativeAllocatorPrefixStepOutClass) {
// First pool check (Let's check over all 16 leases)
EXPECT_EQ("2001:db8::",
- alloc.pickAddress(subnet_, cc_, known_client_, duid_,
- IOAddress("::")).toText());
+ alloc.pickAddress(subnet_, cc_, duid_, IOAddress("::")).toText());
EXPECT_EQ("2001:db8:0:10::",
- alloc.pickAddress(subnet_, cc_, known_client_, duid_,
- IOAddress("::")).toText());
+ alloc.pickAddress(subnet_, cc_, duid_, IOAddress("::")).toText());
EXPECT_EQ("2001:db8:0:20::",
- alloc.pickAddress(subnet_, cc_, known_client_, duid_,
- IOAddress("::")).toText());
+ alloc.pickAddress(subnet_, cc_, duid_, IOAddress("::")).toText());
EXPECT_EQ("2001:db8:0:30::",
- alloc.pickAddress(subnet_, cc_, known_client_, duid_,
- IOAddress("::")).toText());
+ alloc.pickAddress(subnet_, cc_, duid_, IOAddress("::")).toText());
EXPECT_EQ("2001:db8:0:40::",
- alloc.pickAddress(subnet_, cc_, known_client_, duid_,
- IOAddress("::")).toText());
+ alloc.pickAddress(subnet_, cc_, duid_, IOAddress("::")).toText());
EXPECT_EQ("2001:db8:0:50::",
- alloc.pickAddress(subnet_, cc_, known_client_, duid_,
- IOAddress("::")).toText());
+ alloc.pickAddress(subnet_, cc_, duid_, IOAddress("::")).toText());
EXPECT_EQ("2001:db8:0:60::",
- alloc.pickAddress(subnet_, cc_, known_client_, duid_,
- IOAddress("::")).toText());
+ alloc.pickAddress(subnet_, cc_, duid_, IOAddress("::")).toText());
EXPECT_EQ("2001:db8:0:70::",
- alloc.pickAddress(subnet_, cc_, known_client_, duid_,
- IOAddress("::")).toText());
+ alloc.pickAddress(subnet_, cc_, duid_, IOAddress("::")).toText());
EXPECT_EQ("2001:db8:0:80::",
- alloc.pickAddress(subnet_, cc_, known_client_, duid_,
- IOAddress("::")).toText());
+ alloc.pickAddress(subnet_, cc_, duid_, IOAddress("::")).toText());
EXPECT_EQ("2001:db8:0:90::",
- alloc.pickAddress(subnet_, cc_, known_client_, duid_,
- IOAddress("::")).toText());
+ alloc.pickAddress(subnet_, cc_, duid_, IOAddress("::")).toText());
EXPECT_EQ("2001:db8:0:a0::",
- alloc.pickAddress(subnet_, cc_, known_client_, duid_,
- IOAddress("::")).toText());
+ alloc.pickAddress(subnet_, cc_, duid_, IOAddress("::")).toText());
EXPECT_EQ("2001:db8:0:b0::",
- alloc.pickAddress(subnet_, cc_, known_client_, duid_,
- IOAddress("::")).toText());
+ alloc.pickAddress(subnet_, cc_, duid_, IOAddress("::")).toText());
EXPECT_EQ("2001:db8:0:c0::",
- alloc.pickAddress(subnet_, cc_, known_client_, duid_,
- IOAddress("::")).toText());
+ alloc.pickAddress(subnet_, cc_, duid_, IOAddress("::")).toText());
EXPECT_EQ("2001:db8:0:d0::",
- alloc.pickAddress(subnet_, cc_, known_client_, duid_,
- IOAddress("::")).toText());
+ alloc.pickAddress(subnet_, cc_, duid_, IOAddress("::")).toText());
EXPECT_EQ("2001:db8:0:e0::",
- alloc.pickAddress(subnet_, cc_, known_client_, duid_,
- IOAddress("::")).toText());
+ alloc.pickAddress(subnet_, cc_, duid_, IOAddress("::")).toText());
EXPECT_EQ("2001:db8:0:f0::",
- alloc.pickAddress(subnet_, cc_, known_client_, duid_,
- IOAddress("::")).toText());
+ alloc.pickAddress(subnet_, cc_, duid_, IOAddress("::")).toText());
// The second pool is skipped
// Third pool (256 leases, let's check first and last explicitly and the
// rest over in a pool
EXPECT_EQ("2001:db8:2::",
- alloc.pickAddress(subnet_, cc_, known_client_, duid_,
- IOAddress("::")).toText());
+ alloc.pickAddress(subnet_, cc_, duid_, IOAddress("::")).toText());
for (int i = 1; i < 255; i++) {
stringstream exp;
exp << "2001:db8:2:" << hex << i << dec << "::";
EXPECT_EQ(exp.str(),
- alloc.pickAddress(subnet_, cc_, known_client_, duid_,
- IOAddress("::")).toText());
+ alloc.pickAddress(subnet_, cc_, duid_, IOAddress("::")).toText());
}
EXPECT_EQ("2001:db8:2:ff::",
- alloc.pickAddress(subnet_, cc_, known_client_, duid_,
- IOAddress("::")).toText());
+ alloc.pickAddress(subnet_, cc_, duid_, IOAddress("::")).toText());
// Ok, we've iterated over all prefixes in all pools. We now wrap around.
// We're looping over now (iterating over first pool again)
EXPECT_EQ("2001:db8::",
- alloc.pickAddress(subnet_, cc_, known_client_, duid_,
- IOAddress("::")).toText());
+ alloc.pickAddress(subnet_, cc_, duid_, IOAddress("::")).toText());
EXPECT_EQ("2001:db8:0:10::",
- alloc.pickAddress(subnet_, cc_, known_client_, duid_,
- IOAddress("::")).toText());
-}
-
-TEST_F(AllocEngine6Test, IterativeAllocatorPrefixKnown) {
- NakedAllocEngine::NakedIterativeAllocator alloc(Lease::TYPE_PD);
-
- subnet_.reset(new Subnet6(IOAddress("2001:db8::"), 32, 1, 2, 3, 4));
-
- Pool6Ptr pool1(new Pool6(Lease::TYPE_PD, IOAddress("2001:db8::"), 56, 60));
- Pool6Ptr pool2(new Pool6(Lease::TYPE_PD, IOAddress("2001:db8:1::"), 48, 48));
- Pool6Ptr pool3(new Pool6(Lease::TYPE_PD, IOAddress("2001:db8:2::"), 56, 64));
- // Set pool2 in foo
- pool1->setKnownClients(Pool::SERVE_BOTH);
- pool2->setKnownClients(Pool::SERVE_UNKNOWN);
- pool3->setKnownClients(Pool::SERVE_KNOWN);
- subnet_->addPool(pool1);
- subnet_->addPool(pool2);
- subnet_->addPool(pool3);
-
- // Clients have reservations
- known_client_ = true;
-
- // We have a 2001:db8::/48 subnet that has 3 pools defined in it:
- // 2001:db8::/56 split into /60 prefixes (16 leases) (or 2001:db8:0:X0::)
- // 2001:db8:1::/48 split into a single /48 prefix (just 1 lease)
- // 2001:db8:2::/56 split into /64 prefixes (256 leases) (or 2001:db8:2:XX::)
-
- // First pool check (Let's check over all 16 leases)
- EXPECT_EQ("2001:db8::",
- alloc.pickAddress(subnet_, cc_, known_client_, duid_,
- IOAddress("::")).toText());
- EXPECT_EQ("2001:db8:0:10::",
- alloc.pickAddress(subnet_, cc_, known_client_, duid_,
- IOAddress("::")).toText());
- EXPECT_EQ("2001:db8:0:20::",
- alloc.pickAddress(subnet_, cc_, known_client_, duid_,
- IOAddress("::")).toText());
- EXPECT_EQ("2001:db8:0:30::",
- alloc.pickAddress(subnet_, cc_, known_client_, duid_,
- IOAddress("::")).toText());
- EXPECT_EQ("2001:db8:0:40::",
- alloc.pickAddress(subnet_, cc_, known_client_, duid_,
- IOAddress("::")).toText());
- EXPECT_EQ("2001:db8:0:50::",
- alloc.pickAddress(subnet_, cc_, known_client_, duid_,
- IOAddress("::")).toText());
- EXPECT_EQ("2001:db8:0:60::",
- alloc.pickAddress(subnet_, cc_, known_client_, duid_,
- IOAddress("::")).toText());
- EXPECT_EQ("2001:db8:0:70::",
- alloc.pickAddress(subnet_, cc_, known_client_, duid_,
- IOAddress("::")).toText());
- EXPECT_EQ("2001:db8:0:80::",
- alloc.pickAddress(subnet_, cc_, known_client_, duid_,
- IOAddress("::")).toText());
- EXPECT_EQ("2001:db8:0:90::",
- alloc.pickAddress(subnet_, cc_, known_client_, duid_,
- IOAddress("::")).toText());
- EXPECT_EQ("2001:db8:0:a0::",
- alloc.pickAddress(subnet_, cc_, known_client_, duid_,
- IOAddress("::")).toText());
- EXPECT_EQ("2001:db8:0:b0::",
- alloc.pickAddress(subnet_, cc_, known_client_, duid_,
- IOAddress("::")).toText());
- EXPECT_EQ("2001:db8:0:c0::",
- alloc.pickAddress(subnet_, cc_, known_client_, duid_,
- IOAddress("::")).toText());
- EXPECT_EQ("2001:db8:0:d0::",
- alloc.pickAddress(subnet_, cc_, known_client_, duid_,
- IOAddress("::")).toText());
- EXPECT_EQ("2001:db8:0:e0::",
- alloc.pickAddress(subnet_, cc_, known_client_, duid_,
- IOAddress("::")).toText());
- EXPECT_EQ("2001:db8:0:f0::",
- alloc.pickAddress(subnet_, cc_, known_client_, duid_,
- IOAddress("::")).toText());
-
- // The second pool is skipped
-
- // Third pool (256 leases, let's check first and last explicitly and the
- // rest over in a pool
- EXPECT_EQ("2001:db8:2::",
- alloc.pickAddress(subnet_, cc_, known_client_, duid_,
- IOAddress("::")).toText());
- for (int i = 1; i < 255; i++) {
- stringstream exp;
- exp << "2001:db8:2:" << hex << i << dec << "::";
- EXPECT_EQ(exp.str(),
- alloc.pickAddress(subnet_, cc_, known_client_, duid_,
- IOAddress("::")).toText());
-
- }
- EXPECT_EQ("2001:db8:2:ff::",
- alloc.pickAddress(subnet_, cc_, known_client_, duid_,
- IOAddress("::")).toText());
-
- // Ok, we've iterated over all prefixes in all pools. We now wrap around.
- // We're looping over now (iterating over first pool again)
- EXPECT_EQ("2001:db8::",
- alloc.pickAddress(subnet_, cc_, known_client_, duid_,
- IOAddress("::")).toText());
- EXPECT_EQ("2001:db8:0:10::",
- alloc.pickAddress(subnet_, cc_, known_client_, duid_,
- IOAddress("::")).toText());
+ alloc.pickAddress(subnet_, cc_, duid_, IOAddress("::")).toText());
}
// This test verifies that the iterative allocator can step over addresses
NakedAllocEngine::NakedIterativeAllocator alloc(Lease::TYPE_NA);
// Let's pick the first address
- IOAddress addr1 = alloc.pickAddress(subnet_, cc_, known_client_, duid_,
- IOAddress("2001:db8:1::10"));
+ IOAddress addr1 = alloc.pickAddress(subnet_, cc_, duid_, IOAddress("2001:db8:1::10"));
// Check that we can indeed pick the first address from the pool
EXPECT_EQ("2001:db8:1::10", addr1.toText());
std::set<IOAddress> generated_addrs;
int cnt = 0;
while (++cnt) {
- IOAddress candidate = alloc.pickAddress(subnet_, cc_, known_client_,
+ IOAddress candidate = alloc.pickAddress(subnet_, cc_,
duid_, IOAddress("::"));
EXPECT_TRUE(subnet_->inPool(Lease::TYPE_NA, candidate));
IOAddress addr("2001:db8:1::ad");
// Create a subnet with a pool that has one address.
- initSubnet(IOAddress("2001:db8:1::"),
- addr, addr);
+ initSubnet(IOAddress("2001:db8:1::"), addr, addr);
// Initialize FQDN for a lease.
initFqdn("myhost.example.com", true, true);
EXPECT_EQ("2001:db8:1::1", lease->addr_.toText());
}
-// This test verifies that the server can offer an address from a
-// different subnet than orginally selected, when the address pool in
-// the first subnet requires a reservation.
-TEST_F(SharedNetworkAlloc6Test, solicitSharedNetworkPoolKnown) {
- // Try to offer address from subnet1. There is an address available so
- // it should be offerred.
- Pkt6Ptr query(new Pkt6(DHCPV6_SOLICIT, 1234));
- AllocEngine::ClientContext6 ctx(subnet1_, duid_, false, false, "", true,
- query);
- ctx.currentIA().iaid_ = iaid_;
-
- Lease6Ptr lease;
- ASSERT_NO_THROW(lease = expectOneLease(engine_.allocateLeases6(ctx)));
- ASSERT_TRUE(lease);
- ASSERT_TRUE(subnet1_->inRange(lease->addr_));
-
- // Apply restrictions on the pool1. This should be only assigned
- // to clients with have a reservation.
- pool1_->setKnownClients(Pool::SERVE_KNOWN);
-
- // The allocation engine should determine that the pool1 is not
- // available for the client without a reservation.
- // Instead, it should offer an address from subnet2 that belongs
- // to the same shared network.
- AllocEngine::ClientContext6 ctx2(subnet1_, duid_, false, false, "", true,
- query);
- ctx2.currentIA().iaid_ = iaid_;
- ctx2.query_ = query;
- ASSERT_NO_THROW(lease = expectOneLease(engine_.allocateLeases6(ctx2)));
- ASSERT_TRUE(lease);
- ASSERT_TRUE(subnet2_->inRange(lease->addr_));
-
- AllocEngine::ClientContext6 ctx3(subnet1_, duid_, false, false, "", true,
- query);
- ctx3.currentIA().iaid_ = iaid_;
- ctx3.query_ = query;
-
- AllocEngine::ClientContext6 ctx4(subnet1_, duid_, false, false, "", true,
- query);
- ctx4.currentIA().iaid_ = iaid_;
- ctx4.query_ = query;
-
- // Add a host reservation and try again. This time, we should
- // offer an address from the pool1_.
- HostPtr host(new Host(&duid_->getDuid()[0], duid_->getDuid().size(),
- Host::IDENT_DUID, SubnetID(0), subnet1_->getID(),
- IOAddress::IPV4_ZERO_ADDRESS(), "foo"));
- CfgMgr::instance().getStagingCfg()->getCfgHosts()->add(host);
- CfgMgr::instance().commit();
- AllocEngine::findReservation(ctx4);
-
- ASSERT_NO_THROW(lease = expectOneLease(engine_.allocateLeases6(ctx4)));
- ASSERT_TRUE(lease);
- EXPECT_EQ("2001:db8:1::1", lease->addr_.toText());
-}
-
// This test verifies that the client is offerred a reserved address
// even if this address belongs to another subnet within the same
// shared network.
-// Copyright (C) 2015-2017 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2015-2018 Internet Systems Consortium, Inc. ("ISC")
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
bool fqdn_rev_; ///< Perform reverse update for a lease.
LeaseMgrFactory factory_; ///< pointer to LeaseMgr factory
ClientClasses cc_; ///< client classes
- bool known_client_; ///< client has a reservation
};
/// @brief Used in Allocation Engine tests for IPv4
LeaseMgrFactory factory_; ///< Pointer to LeaseMgr factory
AllocEngine::ClientContext4 ctx_; ///< Context information passed to various
ClientClasses cc_; ///< Client classes
- bool known_client_; ///< client has a reservation
///< allocation engine functions.
};
-// Copyright (C) 2014-2017 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2014-2018 Internet Systems Consortium, Inc. ("ISC")
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
Pool4Ptr pool1(new Pool4(IOAddress("192.0.2.1"), IOAddress("192.0.2.10")));
Pool4Ptr pool2(new Pool4(IOAddress("192.0.2.64"), 26));
pool2->allowClientClass("bar");
- pool2->setKnownClients(Pool::SERVE_KNOWN);
pool2->deferClientClass("foo");
subnet->addPool(pool1);
" \"option-data\": [ ],\n"
" \"pool\": \"192.0.2.64/26\",\n"
" \"client-class\": \"bar\",\n"
- " \"known-clients\": \"only\",\n"
" \"eval-client-classes\": [ \"foo\" ]\n"
" }\n"
" ]\n"
IOAddress("2001:db8:1::199")));
Pool6Ptr pool2(new Pool6(Lease::TYPE_NA, IOAddress("2001:db8:1:1::"), 64));
pool2->allowClientClass("bar");
- pool2->setKnownClients(Pool::SERVE_UNKNOWN);
pool2->deferClientClass("foo");
subnet->addPool(pool1);
" \"pool\": \"2001:db8:1:1::/64\",\n"
" \"option-data\": [ ],\n"
" \"client-class\": \"bar\",\n"
- " \"known-clients\": \"never\",\n"
" \"eval-client-classes\": [ \"foo\" ]\n"
" }\n"
" ],\n"
IOAddress("2001:db8:3::"), 64));
pdpool1->deferClientClass("bar");
pdpool2->allowClientClass("bar");
- pdpool2->setKnownClients(Pool::SERVE_KNOWN);
-
subnet->addPool(pdpool1);
subnet->addPool(pdpool2);
" \"excluded-prefix\": \"2001:db8:3::\",\n"
" \"excluded-prefix-len\": 64,\n"
" \"option-data\": [ ],\n"
- " \"client-class\": \"bar\",\n"
- " \"known-clients\": \"only\"\n"
+ " \"client-class\": \"bar\"\n"
" }\n"
" ],\n"
" \"option-data\": [ ]\n"
-// Copyright (C) 2012-2017 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2012-2018 Internet Systems Consortium, Inc. ("ISC")
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// No class restrictions defined, any client should be supported
EXPECT_TRUE(pool->getClientClass().empty());
- EXPECT_TRUE(pool->clientSupported(no_class, false));
- EXPECT_TRUE(pool->clientSupported(foo_class, false));
- EXPECT_TRUE(pool->clientSupported(bar_class, false));
- EXPECT_TRUE(pool->clientSupported(three_classes, false));
+ EXPECT_TRUE(pool->clientSupported(no_class));
+ EXPECT_TRUE(pool->clientSupported(foo_class));
+ EXPECT_TRUE(pool->clientSupported(bar_class));
+ EXPECT_TRUE(pool->clientSupported(three_classes));
// Let's allow only clients belonging to "bar" class.
pool->allowClientClass("bar");
EXPECT_EQ("bar", pool->getClientClass());
- EXPECT_FALSE(pool->clientSupported(no_class, false));
- EXPECT_FALSE(pool->clientSupported(foo_class, false));
- EXPECT_TRUE(pool->clientSupported(bar_class, false));
- EXPECT_TRUE(pool->clientSupported(three_classes, false));
-}
-
-// This test checks that handling for known-clients is valid.
-TEST(Pool4Test, knownClients) {
- // Create a pool.
- Pool4Ptr pool(new Pool4(IOAddress("192.0.2.0"),
- IOAddress("192.0.2.255")));
-
- // This pool serves everybody by default.
- EXPECT_EQ(Pool::SERVE_BOTH, pool->getKnownClients());
-
- // Set it to only known clients.
- pool->setKnownClients(Pool::SERVE_KNOWN);
- EXPECT_EQ(Pool::SERVE_KNOWN,pool->getKnownClients());
+ EXPECT_FALSE(pool->clientSupported(no_class));
+ EXPECT_FALSE(pool->clientSupported(foo_class));
+ EXPECT_TRUE(pool->clientSupported(bar_class));
+ EXPECT_TRUE(pool->clientSupported(three_classes));
}
// This test checks that handling for eval-client-classes is valid.
// No class restrictions defined, any client should be supported
EXPECT_TRUE(pool.getClientClass().empty());
- EXPECT_TRUE(pool.clientSupported(no_class, false));
- EXPECT_TRUE(pool.clientSupported(foo_class, false));
- EXPECT_TRUE(pool.clientSupported(bar_class, false));
- EXPECT_TRUE(pool.clientSupported(three_classes, false));
+ EXPECT_TRUE(pool.clientSupported(no_class));
+ EXPECT_TRUE(pool.clientSupported(foo_class));
+ EXPECT_TRUE(pool.clientSupported(bar_class));
+ EXPECT_TRUE(pool.clientSupported(three_classes));
// Let's allow only clients belonging to "bar" class.
pool.allowClientClass("bar");
EXPECT_EQ("bar", pool.getClientClass());
- EXPECT_FALSE(pool.clientSupported(no_class, false));
- EXPECT_FALSE(pool.clientSupported(foo_class, false));
- EXPECT_TRUE(pool.clientSupported(bar_class, false));
- EXPECT_TRUE(pool.clientSupported(three_classes, false));
-}
-
-// This test checks that handling for known-clients is valid.
-TEST(Pool6Test, knownClients) {
- // Create a pool.
- Pool6 pool(Lease::TYPE_NA, IOAddress("2001:db8::1"),
- IOAddress("2001:db8::2"));
-
- // This pool serves everybody by default.
- EXPECT_EQ(Pool::SERVE_BOTH, pool.getKnownClients());
-
- // Set it to only known clients.
- pool.setKnownClients(Pool::SERVE_KNOWN);
- EXPECT_EQ(Pool::SERVE_KNOWN,pool.getKnownClients());
+ EXPECT_FALSE(pool.clientSupported(no_class));
+ EXPECT_FALSE(pool.clientSupported(foo_class));
+ EXPECT_TRUE(pool.clientSupported(bar_class));
+ EXPECT_TRUE(pool.clientSupported(three_classes));
}
// This test checks that handling for eval-client-classes is valid.
-// Copyright (C) 2012-2017 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2012-2018 Internet Systems Consortium, Inc. ("ISC")
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
three_classes.insert("baz");
// If we provide a hint, we should get a pool that this hint belongs to
- ASSERT_NO_THROW(mypool = subnet->getPool(Lease::TYPE_V4, no_class, false,
+ ASSERT_NO_THROW(mypool = subnet->getPool(Lease::TYPE_V4, no_class,
IOAddress("192.1.2.201")));
EXPECT_EQ(mypool, pool4);
- ASSERT_NO_THROW(mypool = subnet->getPool(Lease::TYPE_V4, no_class, false,
+ ASSERT_NO_THROW(mypool = subnet->getPool(Lease::TYPE_V4, no_class,
IOAddress("192.1.2.129")));
EXPECT_EQ(mypool, pool2);
- ASSERT_NO_THROW(mypool = subnet->getPool(Lease::TYPE_V4, no_class, false,
+ ASSERT_NO_THROW(mypool = subnet->getPool(Lease::TYPE_V4, no_class,
IOAddress("192.1.2.64")));
EXPECT_EQ(mypool, pool1);
// Specify addresses which don't belong to any existing pools.
- ASSERT_NO_THROW(mypool = subnet->getPool(Lease::TYPE_V4, three_classes, false,
+ ASSERT_NO_THROW(mypool = subnet->getPool(Lease::TYPE_V4, three_classes,
IOAddress("192.1.2.210")));
EXPECT_FALSE(mypool);
// Pool3 requires a member of bar
- ASSERT_NO_THROW(mypool = subnet->getPool(Lease::TYPE_V4, no_class, false,
+ ASSERT_NO_THROW(mypool = subnet->getPool(Lease::TYPE_V4, no_class,
IOAddress("192.1.2.195")));
EXPECT_FALSE(mypool);
- ASSERT_NO_THROW(mypool = subnet->getPool(Lease::TYPE_V4, foo_class, false,
+ ASSERT_NO_THROW(mypool = subnet->getPool(Lease::TYPE_V4, foo_class,
IOAddress("192.1.2.195")));
EXPECT_FALSE(mypool);
- ASSERT_NO_THROW(mypool = subnet->getPool(Lease::TYPE_V4, bar_class, false,
+ ASSERT_NO_THROW(mypool = subnet->getPool(Lease::TYPE_V4, bar_class,
IOAddress("192.1.2.195")));
EXPECT_EQ(mypool, pool3);
- ASSERT_NO_THROW(mypool = subnet->getPool(Lease::TYPE_V4, three_classes, false,
+ ASSERT_NO_THROW(mypool = subnet->getPool(Lease::TYPE_V4, three_classes,
IOAddress("192.1.2.195")));
EXPECT_EQ(mypool, pool3);
-
- // And now known clients
- EXPECT_EQ(Pool::SERVE_BOTH, pool1->getKnownClients());
- pool2->setKnownClients(Pool::SERVE_KNOWN);
- pool3->setKnownClients(Pool::SERVE_UNKNOWN);
- pool4->setKnownClients(Pool::SERVE_UNKNOWN);
-
- ASSERT_NO_THROW(mypool = subnet->getPool(Lease::TYPE_V4, no_class, false,
- IOAddress("192.1.2.64")));
- EXPECT_EQ(mypool, pool1);
- ASSERT_NO_THROW(mypool = subnet->getPool(Lease::TYPE_V4, no_class, true,
- IOAddress("192.1.2.64")));
- EXPECT_EQ(mypool, pool1);
- ASSERT_NO_THROW(mypool = subnet->getPool(Lease::TYPE_V4, no_class, false,
- IOAddress("192.1.2.129")));
- EXPECT_FALSE(mypool);
- ASSERT_NO_THROW(mypool = subnet->getPool(Lease::TYPE_V4, no_class, true,
- IOAddress("192.1.2.129")));
-
- EXPECT_EQ(mypool, pool2);
- ASSERT_NO_THROW(mypool = subnet->getPool(Lease::TYPE_V4, no_class, false,
- IOAddress("192.1.2.195")));
- EXPECT_FALSE(mypool);
- ASSERT_NO_THROW(mypool = subnet->getPool(Lease::TYPE_V4, no_class, true,
- IOAddress("192.1.2.195")));
- EXPECT_FALSE(mypool);
- ASSERT_NO_THROW(mypool = subnet->getPool(Lease::TYPE_V4, bar_class, false,
- IOAddress("192.1.2.195")));
- EXPECT_EQ(mypool, pool3);
- ASSERT_NO_THROW(mypool = subnet->getPool(Lease::TYPE_V4, bar_class, true,
- IOAddress("192.1.2.195")));
- EXPECT_FALSE(mypool);
- ASSERT_NO_THROW(mypool = subnet->getPool(Lease::TYPE_V4, no_class, false,
- IOAddress("192.1.2.201")));
- EXPECT_EQ(mypool, pool4);
- ASSERT_NO_THROW(mypool = subnet->getPool(Lease::TYPE_V4, no_class, true,
- IOAddress("192.1.2.201")));
- EXPECT_FALSE(mypool);
}
// Check if it's possible to get specified number of possible leases for
pool3->allowClientClass("bar");
// Pool3 requires a member of bar
- EXPECT_EQ(196, subnet->getPoolCapacity(Lease::TYPE_V4, no_class, false));
- EXPECT_EQ(196, subnet->getPoolCapacity(Lease::TYPE_V4, foo_class, false));
- EXPECT_EQ(200, subnet->getPoolCapacity(Lease::TYPE_V4, bar_class, false));
- EXPECT_EQ(200, subnet->getPoolCapacity(Lease::TYPE_V4, three_classes, false));
-
- // And now known clients
- EXPECT_EQ(Pool::SERVE_BOTH, pool1->getKnownClients());
- pool2->setKnownClients(Pool::SERVE_KNOWN);
- pool3->setKnownClients(Pool::SERVE_UNKNOWN);
-
- EXPECT_EQ(132, subnet->getPoolCapacity(Lease::TYPE_V4, no_class, false));
- EXPECT_EQ(196, subnet->getPoolCapacity(Lease::TYPE_V4, no_class, true));
- EXPECT_EQ(136, subnet->getPoolCapacity(Lease::TYPE_V4, bar_class, false));
- EXPECT_EQ(196, subnet->getPoolCapacity(Lease::TYPE_V4, bar_class, true));
+ EXPECT_EQ(196, subnet->getPoolCapacity(Lease::TYPE_V4, no_class));
+ EXPECT_EQ(196, subnet->getPoolCapacity(Lease::TYPE_V4, foo_class));
+ EXPECT_EQ(200, subnet->getPoolCapacity(Lease::TYPE_V4, bar_class));
+ EXPECT_EQ(200, subnet->getPoolCapacity(Lease::TYPE_V4, three_classes));
}
// Checks that it is not allowed to add invalid pools.
// This client does not belong to any class.
isc::dhcp::ClientClasses no_class;
- EXPECT_FALSE(subnet->inPool(Lease::TYPE_V4, IOAddress("192.2.3.4"), no_class, false));
+ EXPECT_FALSE(subnet->inPool(Lease::TYPE_V4, IOAddress("192.2.3.4"), no_class));
// This client belongs to foo only
isc::dhcp::ClientClasses foo_class;
foo_class.insert("foo");
- EXPECT_FALSE(subnet->inPool(Lease::TYPE_V4, IOAddress("192.2.3.4"), foo_class, false));
+ EXPECT_FALSE(subnet->inPool(Lease::TYPE_V4, IOAddress("192.2.3.4"), foo_class));
// This client belongs to bar only. I like that client.
isc::dhcp::ClientClasses bar_class;
bar_class.insert("bar");
- EXPECT_TRUE(subnet->inPool(Lease::TYPE_V4, IOAddress("192.2.3.4"), bar_class, false));
+ EXPECT_TRUE(subnet->inPool(Lease::TYPE_V4, IOAddress("192.2.3.4"), bar_class));
// This client belongs to foo, bar and baz classes.
isc::dhcp::ClientClasses three_classes;
three_classes.insert("foo");
three_classes.insert("bar");
three_classes.insert("baz");
- EXPECT_TRUE(subnet->inPool(Lease::TYPE_V4, IOAddress("192.2.3.4"), three_classes, false));
-
- // Add known clients
- pool1->setKnownClients(Pool::SERVE_UNKNOWN);
- EXPECT_TRUE(subnet->inPool(Lease::TYPE_V4, IOAddress("192.2.3.4"), three_classes, false));
- EXPECT_FALSE(subnet->inPool(Lease::TYPE_V4, IOAddress("192.2.3.4"), three_classes, true));
+ EXPECT_TRUE(subnet->inPool(Lease::TYPE_V4, IOAddress("192.2.3.4"), three_classes));
}
// This test checks if the toText() method returns text representation
// Pool3 requires a member of bar
EXPECT_EQ(uint64_t(4294967296ull + 65536),
- subnet->getPoolCapacity(Lease::TYPE_NA, no_class, false));
+ subnet->getPoolCapacity(Lease::TYPE_NA, no_class));
EXPECT_EQ(uint64_t(4294967296ull + 65536),
- subnet->getPoolCapacity(Lease::TYPE_NA, foo_class, false));
+ subnet->getPoolCapacity(Lease::TYPE_NA, foo_class));
EXPECT_EQ(uint64_t(4294967296ull + 4294967296ull + 65536),
- subnet->getPoolCapacity(Lease::TYPE_NA, bar_class, false));
+ subnet->getPoolCapacity(Lease::TYPE_NA, bar_class));
EXPECT_EQ(uint64_t(4294967296ull + 4294967296ull + 65536),
- subnet->getPoolCapacity(Lease::TYPE_NA, three_classes, false));
-
- // Add known clients
- pool2->setKnownClients(Pool::SERVE_KNOWN);
- EXPECT_EQ(uint64_t(65536),
- subnet->getPoolCapacity(Lease::TYPE_NA, no_class, false));
- EXPECT_EQ(uint64_t(4294967296ull + 65536),
- subnet->getPoolCapacity(Lease::TYPE_NA, no_class, true));
-
- // This is 2^64 prefixes. We're overflown uint64_t.
- PoolPtr pool4(new Pool6(Lease::TYPE_NA, IOAddress("2001:db8:1:4::"), 64));
- subnet->addPool(pool4);
- EXPECT_EQ(std::numeric_limits<uint64_t>::max(),
- subnet->getPoolCapacity(Lease::TYPE_NA));
-
- PoolPtr pool5(new Pool6(Lease::TYPE_NA, IOAddress("2001:db8:1:5::"), 64));
- subnet->addPool(pool5);
- EXPECT_EQ(std::numeric_limits<uint64_t>::max(),
- subnet->getPoolCapacity(Lease::TYPE_NA));
+ subnet->getPoolCapacity(Lease::TYPE_NA, three_classes));
}
// Test checks whether the number of prefixes available in the pools are
pool3->allowClientClass("bar");
// Pool3 requires a member of bar
- mypool = subnet->getPool(Lease::TYPE_NA, no_class, false,
+ mypool = subnet->getPool(Lease::TYPE_NA, no_class,
IOAddress("2001:db8:1:3::dead:beef"));
EXPECT_FALSE(mypool);
- mypool = subnet->getPool(Lease::TYPE_NA, foo_class, false,
+ mypool = subnet->getPool(Lease::TYPE_NA, foo_class,
IOAddress("2001:db8:1:3::dead:beef"));
EXPECT_FALSE(mypool);
- mypool = subnet->getPool(Lease::TYPE_NA, bar_class, false,
+ mypool = subnet->getPool(Lease::TYPE_NA, bar_class,
IOAddress("2001:db8:1:3::dead:beef"));
EXPECT_EQ(mypool, pool3);
- mypool = subnet->getPool(Lease::TYPE_NA, three_classes, false,
+ mypool = subnet->getPool(Lease::TYPE_NA, three_classes,
IOAddress("2001:db8:1:3::dead:beef"));
EXPECT_EQ(mypool, pool3);
-
- // Add know cients
- pool3->setKnownClients(Pool::SERVE_UNKNOWN);
- mypool = subnet->getPool(Lease::TYPE_NA, no_class, false,
- IOAddress("2001:db8:1:3::dead:beef"));
- EXPECT_FALSE(mypool);
- mypool = subnet->getPool(Lease::TYPE_NA, no_class, true,
- IOAddress("2001:db8:1:3::dead:beef"));
- EXPECT_FALSE(mypool);
- mypool = subnet->getPool(Lease::TYPE_NA, foo_class, false,
- IOAddress("2001:db8:1:3::dead:beef"));
- EXPECT_FALSE(mypool);
- mypool = subnet->getPool(Lease::TYPE_NA, foo_class, true,
- IOAddress("2001:db8:1:3::dead:beef"));
- EXPECT_FALSE(mypool);
- mypool = subnet->getPool(Lease::TYPE_NA, bar_class, false,
- IOAddress("2001:db8:1:3::dead:beef"));
- EXPECT_EQ(mypool, pool3);
- mypool = subnet->getPool(Lease::TYPE_NA, bar_class, true,
- IOAddress("2001:db8:1:3::dead:beef"));
- EXPECT_FALSE(mypool);
- mypool = subnet->getPool(Lease::TYPE_NA, three_classes, false,
- IOAddress("2001:db8:1:3::dead:beef"));
- EXPECT_EQ(mypool, pool3);
- mypool = subnet->getPool(Lease::TYPE_NA, three_classes, true,
- IOAddress("2001:db8:1:3::dead:beef"));
- EXPECT_FALSE(mypool);
}
// Check if Subnet6 supports different types of pools properly.
// This client does not belong to any class.
isc::dhcp::ClientClasses no_class;
- EXPECT_FALSE(subnet->inPool(Lease::TYPE_NA, IOAddress("2001:db8::18"), no_class, false));
+ EXPECT_FALSE(subnet->inPool(Lease::TYPE_NA, IOAddress("2001:db8::18"), no_class));
// This client belongs to foo only
isc::dhcp::ClientClasses foo_class;
foo_class.insert("foo");
- EXPECT_FALSE(subnet->inPool(Lease::TYPE_NA, IOAddress("2001:db8::18"), foo_class, false));
+ EXPECT_FALSE(subnet->inPool(Lease::TYPE_NA, IOAddress("2001:db8::18"), foo_class));
// This client belongs to bar only. I like that client.
isc::dhcp::ClientClasses bar_class;
bar_class.insert("bar");
- EXPECT_TRUE(subnet->inPool(Lease::TYPE_NA, IOAddress("2001:db8::18"), bar_class, false));
+ EXPECT_TRUE(subnet->inPool(Lease::TYPE_NA, IOAddress("2001:db8::18"), bar_class));
// This client belongs to foo, bar and baz classes.
isc::dhcp::ClientClasses three_classes;
three_classes.insert("foo");
three_classes.insert("bar");
three_classes.insert("baz");
- EXPECT_TRUE(subnet->inPool(Lease::TYPE_NA, IOAddress("2001:db8::18"), three_classes, false));
-
- // Add known clients
- pool1->setKnownClients(Pool::SERVE_KNOWN);
- EXPECT_FALSE(subnet->inPool(Lease::TYPE_NA, IOAddress("2001:db8::18"), three_classes, false));
- EXPECT_TRUE(subnet->inPool(Lease::TYPE_NA, IOAddress("2001:db8::18"), three_classes, true));
+ EXPECT_TRUE(subnet->inPool(Lease::TYPE_NA, IOAddress("2001:db8::18"), three_classes));
}
// This test verifies that inRange() and inPool() methods work properly