pref_lifetime INT UNSIGNED, # Preferred lifetime
lease_type TINYINT, # Lease type (see lease6_types
# table for possible values)
- iaid INT UNSIGNED, # See Section 12 of RFC 8415
+ iaid INT UNSIGNED, # See Section 12 of RFC 9915
prefix_len TINYINT UNSIGNED, # For IA_PD only
fqdn_fwd BOOL, # Has forward DNS update been performed by a server
fqdn_rev BOOL, # Has reverse DNS update been performed by a server
pref_lifetime BIGINT, -- Preferred lifetime
lease_type SMALLINT, -- Lease type (see lease6_types
-- table for possible values)
- iaid INT, -- See Section 12 of RFC 8415
+ iaid INT, -- See Section 12 of RFC 9915
prefix_len SMALLINT, -- For IA_PD only
fqdn_fwd BOOLEAN, -- Has forward DNS update been performed by a server
fqdn_rev BOOLEAN, -- Has reverse DNS update been performed by a server
For each incoming packet, @ref isc::dhcp::Dhcpv6Srv::classifyPacket() method is
called. It attempts to extract content of the vendor class option and interprets
-as a name of the class. Although the RFC 8415 says that the vendor class may
+as a name of the class. Although the RFC 9915 says that the vendor class may
contain more than one chunk of data, the existing code handles only one data
block, because that is what actual devices use. For now, the code has been
tested with two classes used in cable modem networks: eRouter1.0 and docsis3.0,
bool
Dhcpv6Srv::testServerID(const Pkt6Ptr& pkt) {
/// @todo Currently we always check server identifier regardless if
- /// it is allowed in the received message or not (per RFC 8415).
+ /// it is allowed in the received message or not (per RFC 9915).
/// If the server identifier is not allowed in the message, the
/// sanityCheck function should deal with it.
OptionPtr server_id = pkt->getOption(D6O_SERVERID);
bool
Dhcpv6Srv::testUnicast(const Pkt6Ptr& pkt) const {
- switch (pkt->getType()) {
- case DHCPV6_SOLICIT:
- case DHCPV6_CONFIRM:
- case DHCPV6_REBIND:
- case DHCPV6_INFORMATION_REQUEST:
- if (pkt->relay_info_.empty() && !pkt->getLocalAddr().isV6Multicast()) {
- LOG_DEBUG(bad_packet6_logger, DBGLVL_PKT_HANDLING, DHCP6_PACKET_DROP_UNICAST)
- .arg(pkt->getLabel())
- .arg(pkt->getName());
- StatsMgr::instance().addValue("pkt6-rfc-violation",
- static_cast<int64_t>(1));
- return (false);
- }
- break;
- default:
- // do nothing
- ;
+ if (pkt->relay_info_.empty() && !pkt->getLocalAddr().isV6Multicast()) {
+ LOG_DEBUG(bad_packet6_logger, DBGLVL_PKT_HANDLING, DHCP6_PACKET_DROP_UNICAST)
+ .arg(pkt->getLabel())
+ .arg(pkt->getName());
+ StatsMgr::instance().addValue("pkt6-rfc-violation",
+ static_cast<int64_t>(1));
+ return (false);
}
return (true);
}
}
// Check if the received query has been sent to unicast or multicast.
- // The Solicit, Confirm, Rebind and Information Request will be
- // discarded if sent to unicast address.
+ // All queries per RFC 9915 will be discarded if sent to unicast address.
if (!testUnicast(query)) {
// Increase the statistic of dropped packets.
setTeeTimes(min_preferred_lft, subnet, ia_rsp);
} else {
// The server wasn't able allocate new lease and renew an existing
- // lease. In that case, the server sends NoAddrsAvail per RFC 8415.
+ // lease. In that case, the server sends NoAddrsAvail per RFC 9915.
ia_rsp->addOption(createStatusCode(*query, *ia_rsp,
STATUS_NoAddrsAvail,
"Sorry, no addresses could be"
// information about client's leases from lease database. We treat this
// as no binding for the client.
if (!subnet) {
- // Per RFC 8415, section 18.3.4, if there is no binding and we are
+ // Per RFC 9915, section 18.3.4, if there is no binding and we are
// processing a Renew, the NoBinding status code should be returned.
if (query->getType() == DHCPV6_RENEW) {
// Insert status code NoBinding
" for this duid/iaid."));
return (ia_rsp);
- // Per RFC 8415, section 18.3.5, if there is no binding and we are
+ // Per RFC 9915, section 18.3.5, if there is no binding and we are
// processing Rebind, the message has to be discarded (assuming that
// the server doesn't know if the prefix in the IA_PD option is
// appropriate for the client's link). The exception being thrown
/// being able to select the subnet may not be enough, because
/// there might be other DHCP servers around that are configured
/// to handle that subnet. Therefore we don't fully follow all
- /// the paths in section 18.3.5 of RFC 8415 to respond with
+ /// the paths in section 18.3.5 of RFC 9915 to respond with
/// zero lifetimes for the prefixes being rebound.
isc_throw(DHCPv6DiscardMessageError, "no subnet found for the"
" client sending Rebind to extend lifetime of the"
} else {
// All is left is to insert the status code.
// The server wasn't able allocate new lease and renew an existing
- // lease. In that case, the server sends NoPrefixAvail per RFC 8415.
+ // lease. In that case, the server sends NoPrefixAvail per RFC 9915.
ia_rsp->addOption(createStatusCode(*query, *ia_rsp,
STATUS_NoPrefixAvail,
"Sorry, no prefixes could be"
// RELEASE message. IA_TA options are ignored.
/// @todo Consider supporting more than one address in a single IA.
- /// It is allowed by RFC 8415, but it is not widely implemented. The only
+ /// It is allowed by RFC 9915, but it is not widely implemented. The only
/// software that supports that is Dibbler, but its author seriously doubts
/// if anyone is really using it. Clients that want more than one address
/// or prefix just include more instances of IA options.
LOG_INFO(lease6_logger, DHCP6_DECLINE_FAIL_NO_LEASE)
.arg(decline->getLabel()).arg(decline_addr->getAddress().toText());
- // According to RFC 8415, section 18.3.8:
+ // According to RFC 9915, section 18.3.8:
// "For each IA in the Decline message for which the server has no
// binding information, the server adds an IA option using the IAID
// from the Decline message and includes a Status Code option with
setStatusCode(ia_rsp, createStatusCode(*decline, *ia_rsp, STATUS_NoBinding,
"Server does not know about such an address."));
- // In the same section of RFC 8415:
+ // In the same section of RFC 9915:
// "The server ignores addresses not assigned to the IAs (though it may"
// choose to log an error if it finds such addresses)."
continue; // There may be other addresses.
/// @brief Check if the message can be sent to unicast.
///
- /// This function checks if the received message conforms to the section 16
- /// of RFC 8415 which says that: "A server MUST discard any Solicit, Confirm,
- /// Rebind or Information-request messages it receives with a Layer 3 unicast
- /// destination address.
+ /// RFC 9915 updated to refuse all messages from clients.
///
/// @param pkt DHCPv6 message to be checked.
- /// @return false if the message has been sent to unicast address but it is
- /// not allowed according to RFC3315, section 15; true otherwise.
+ /// @return false if the message has been sent to unicast address.
bool testUnicast(const Pkt6Ptr& pkt) const;
/// @brief Verifies if specified packet meets RFC requirements
/// @brief Processes incoming Confirm message and returns Reply.
///
/// This function processes Confirm message from the client according
- /// to section 18.3.3. of RFC 8415. It discards the Confirm message if
+ /// to section 18.3.3. of RFC 9915. It discards the Confirm message if
/// the message sent by the client contains no addresses, i.e. it has
/// no IA_NA options or all IA_NA options contain no IAAddr options.
///
/// The behavior of this function is different than @c extendIA_NA in that
/// when there is no subnet found for the rebinding case, the Rebind message
/// is discarded by the server. That behavior is based on the following
- /// statement from the RFC 8415, section 18.3.5:
+ /// statement from the RFC 9915, section 18.3.5:
///
/// "If the server chooses to not include any IAs containing IA Address or
/// IA Prefix options with lifetimes of 0 and the server does not include
///
/// @todo We should consider unification of the server behavior for address
/// assignment and prefix delegation with respect to Rebind message
- /// processing. The RFC 8415, section 18.3.5 doesn't really differentiate
+ /// processing. The RFC 9915, section 18.3.5 doesn't really differentiate
/// between IA_NA and IA_PD in how they should be processed by the server.
/// The intention of the spec is as follows:
///
pools1[0]->toText());
EXPECT_EQ("type=IA_NA, 2001:db8:1:0:abcd::-2001:db8:1:0:abcd::ffff, delegated_len=128",
pools1[1]->toText());
- // There shouldn't be any TA or PD pools
- EXPECT_TRUE((*subnet)->getPools(Lease::TYPE_TA).empty());
+ // There shouldn't be any PD pools
EXPECT_TRUE((*subnet)->getPools(Lease::TYPE_PD).empty());
// Check the second subnet
pools2[0]->toText());
EXPECT_EQ("type=IA_NA, 2001:db8:2::300-2001:db8:2::3ff, delegated_len=128",
pools2[1]->toText());
- // There shouldn't be any TA or PD pools
- EXPECT_TRUE((*subnet)->getPools(Lease::TYPE_TA).empty());
+ // There shouldn't be any PD pools
EXPECT_TRUE((*subnet)->getPools(Lease::TYPE_PD).empty());
}
// Test that directly connected client's Confirm message is processed and Reply
// message is sent back. In this test case, the client sends Confirm for two
// addresses that belong to the same IAID and are sent within the same IA_NA
-// option (RFC 8415, section 18.3.3).
+// option (RFC 9915, section 18.3.3).
TEST_F(ConfirmTest, directClientSameIAID) {
Dhcp6Client client(srv_);
// Configure client to request IA_NA.
// Test that directly connected client's Confirm message is processed and Reply
// message is sent back. In this test case, the client sends Confirm for two
// addresses that belong to different IAIDs and are sent within the different
-// IA_NA options (RFC 8415, section 18.3.3).
+// IA_NA options (RFC 9915, section 18.3.3).
TEST_F(ConfirmTest, directClientDifferentIAID) {
Dhcp6Client client(srv_);
// Configure client to request IA_NA.
// Test that relayed client's Confirm message is processed and Reply message
-// is sent back (RFC 8415, section 18.3.3).
+// is sent back (RFC 9915, section 18.3.3).
TEST_F(ConfirmTest, relayedClient) {
Dhcp6Client client(srv_);
// Client to send relayed message.
}
// Test that the Confirm message without any addresses is discarded
-// (RFC 8415, section 18.3.3).
+// (RFC 9915, section 18.3.3).
TEST_F(ConfirmTest, relayedClientNoAddress) {
Dhcp6Client client(srv_);
// Configure the server.
}
// This test checks that the server processes Confirm message correctly if
-// the subnet can't be selected for the client (RFC 8415, section 18.3.3).
+// the subnet can't be selected for the client (RFC 9915, section 18.3.3).
TEST_F(ConfirmTest, relayedClientNoSubnet) {
Dhcp6Client client(srv_);
// Client to send relayed message.
}
// This test checks that the Confirm message is discarded by the server if it
-// has been sent to unicast address (RFC 8415, section 18.3.3).
+// has been sent to unicast address (RFC 9915, section 18).
TEST_F(ConfirmTest, unicast) {
Dhcp6Client client(srv_);
// Configure client to request IA_NA.
copyIAsFromLeases(query);
// During the Renew the client may request additional bindings per
- // RFC 8415.
+ // RFC 9915.
appendRequestedIAs(query);
context_.query_ = query;
copyIAsFromLeases(query);
// During the Rebind the client may request additional bindings per
- // RFC 8415.
+ // RFC 9915.
appendRequestedIAs(query);
// Add Client FQDN if configured.
///
/// This method is typically called to specify IA_NA options to be
/// sent to the server during 4-way handshakes and during lease
- /// renewal to request allocation of new leases (as per RFC 8415).
+ /// renewal to request allocation of new leases (as per RFC 9915).
///
/// @param iaid IAID.
/// @param address IPv6 address to be included in the IA_NA. It defaults
///
/// This method is typically called to specify IA_PD options to be
/// sent to the server during 4-way handshakes and during lease
- /// renewal to request allocation of new leases (as per RFC 8415).
+ /// renewal to request allocation of new leases (as per RFC 9915).
///
/// @param iaid IAID.
/// @param prefix_len Prefix length.
// No failure here. There's really no way for test LL DUID. It doesn't
// even make sense to check if that Link Layer is actually present on
- // a physical interface. RFC 8415 says a server should write its DUID
+ // a physical interface. RFC 9915 says a server should write its DUID
// and keep it despite hardware changes.
break;
}
// sent to unicast address.
const uint8_t not_allowed_unicast[] = {
DHCPV6_SOLICIT,
+ DHCPV6_REQUEST,
DHCPV6_CONFIRM,
+ DHCPV6_RENEW,
DHCPV6_REBIND,
+ DHCPV6_RELEASE,
+ DHCPV6_DECLINE,
DHCPV6_INFORMATION_REQUEST
};
// Iterate over these messages and make sure they are discarded.
EXPECT_FALSE(srv_->testUnicast(msg))
<< "server accepts message type "
<< static_cast<int>(not_allowed_unicast[i])
- << "being sent to unicast address; this message should"
- " be discarded according to section 18.4 of RFC 8415";
+ << " being sent to unicast address; this message should"
+ " be discarded according to section 18 of RFC 9915";
}
// The pkt6-rfc-violation stat should be bumped by one each time.
// Explicitly list client/relay message types which are allowed to
// be sent to unicast.
const uint8_t allowed_unicast[] = {
- DHCPV6_REQUEST,
- DHCPV6_RENEW,
- DHCPV6_RELEASE,
- DHCPV6_DECLINE,
DHCPV6_RELAY_FORW
};
// Iterate over these messages and check that they are accepted being
for (size_t i = 0; i < sizeof(allowed_unicast); ++i) {
Pkt6Ptr msg = Pkt6Ptr(new Pkt6(allowed_unicast[i], 1234));
msg->setLocalAddr(IOAddress("2001:db8:1::1"));
- msg->addOption(srv_->getServerID());
+ Pkt6::RelayInfo relay;
+ relay.linkaddr_ = IOAddress("2001:db8:2::1234");
+ relay.peeraddr_ = IOAddress("fe80::1");
+ // In fact what matters is the packet was relayed...
+ msg->relay_info_.push_back(relay);
EXPECT_TRUE(srv_->testUnicast(msg))
<< "server doesn't accept message type "
<< static_cast<int>(allowed_unicast[i])
- << "being sent to unicast address";
+ << " being sent to unicast address";
}
}
checkIA_NAStatusCode(ia, STATUS_Success, 0, 0);
checkMsgStatusCode(reply, STATUS_Success);
- // There should be no address returned in RELEASE (see RFC 8415, 18.3.7)
+ // There should be no address returned in RELEASE (see RFC 9915, 18.3.7)
// There should be no prefix
EXPECT_FALSE(tmp->getOption(D6O_IAADDR));
EXPECT_FALSE(tmp->getOption(D6O_IAPREFIX));
checkIA_NAStatusCode(ia, STATUS_Success, 0, 0);
checkMsgStatusCode(reply, STATUS_Success);
- // There should be no address returned in RELEASE (see RFC 8415, 18.3.7)
+ // There should be no address returned in RELEASE (see RFC 9915, 18.3.7)
// There should be no prefix
EXPECT_FALSE(tmp->getOption(D6O_IAADDR));
EXPECT_FALSE(tmp->getOption(D6O_IAPREFIX));
client.config_.leases_[0].addr_ = IOAddress("2001:db8:1:10::");
// Try to Rebind. The client will use correct IAID but will specify a
// wrong prefix. The server will discover that the client has a binding
- // but the prefix will not match. According to the RFC 8415, section 18.3.5
+ // but the prefix will not match. According to the RFC 9915, section 18.3.5
// the server may return delegated prefix with lifetime of 0 when it
// finds that the lease entry for the particular IAID but the prefix
// is not appropriate. This constitutes explicit notification to the
/// @todo Extend PD tests to cover same prefix by different length.
// This test checks that the Rebind message is discarded by the server if it
-// has been sent to unicast address (RFC 8415, section 18.4).
+// has been sent to unicast address (RFC 9915, section 18).
TEST_F(RebindTest, unicast) {
Dhcp6Client client(srv_);
// Configure client to request IA_NA.
Lease6 lease_client = client.getLease(0);
// Set the unicast destination address for the Rebind message.
// The Rebind should be discarded when sent to unicast address,
- // according to section 18.4 of RFC 8415.
+ // according to section 18 of RFC 9915.
client.setDestAddress(IOAddress("2001:db8:1::1"));
// Send the Rebind message to a unicast address.
ASSERT_NO_THROW(client.doRebind());
}
// Get server argument
- // NoteFF02::1:2 and FF02::1:3 are defined in RFC 8415 as
+ // NoteFF02::1:2 and FF02::1:3 are defined in RFC 9915 as
// All_DHCP_Relay_Agents_and_Servers and All_DHCP_Servers
// addresses
check(optind < argc -1, "extra arguments?");
duid_template_[2] = HWTYPE_ETHERNET >> 8;
duid_template_[3] = HWTYPE_ETHERNET & 0xff;
- // As described in RFC 8415: 'the time value is the time
+ // As described in RFC 9915: 'the time value is the time
// that the DUID is generated represented in seconds
// since midnight (UTC), January 1, 2000, modulo 2^32.'
ptime now = microsec_clock::universal_time();
EXPECT_TRUE(std::equal(new_duid.begin(), new_duid.begin() + 4,
duid_llt_and_hw));
- // As described in RFC 8415: 'the time value is the time
+ // As described in RFC 9915: 'the time value is the time
// that the DUID is generated represented in seconds
// since midnight (UTC), January 1, 2000, modulo 2^32.'
uint32_t duid_time = 0;
for (size_t i = 0; i < relay_infos.size(); ++i) {
RelayInfoPtr relay = relay_infos[i];
- // build relay-forw/relay-repl header (see RFC 8415, section 9)
+ // build relay-forw/relay-repl header (see RFC 9915, section 9)
buffer_out.writeUint8(DHCPV6_RELAY_FORW);
buffer_out.writeUint8(relay->hop_count_);
buffer_out.writeData(&(relay->linkaddr_.toBytes()[0]),
/* DHCPv6 Option codes: */
enum DHCPv6OptionType {
- D6O_CLIENTID = 1, /* RFC8415 */
- D6O_SERVERID = 2, /* RFC8415 */
- D6O_IA_NA = 3, /* RFC8415 */
- D6O_IA_TA = 4, /* RFC8415 */
- D6O_IAADDR = 5, /* RFC8415 */
- D6O_ORO = 6, /* RFC8415 */
- D6O_PREFERENCE = 7, /* RFC8415 */
- D6O_ELAPSED_TIME = 8, /* RFC8415 */
- D6O_RELAY_MSG = 9, /* RFC8415 */
+ D6O_CLIENTID = 1, /* RFC9915 */
+ D6O_SERVERID = 2, /* RFC9915 */
+ D6O_IA_NA = 3, /* RFC9915 */
+ D6O_IA_TA = 4, /* RFC9915 (deprecated) */
+ D6O_IAADDR = 5, /* RFC9915 */
+ D6O_ORO = 6, /* RFC9915 */
+ D6O_PREFERENCE = 7, /* RFC9915 */
+ D6O_ELAPSED_TIME = 8, /* RFC9915 */
+ D6O_RELAY_MSG = 9, /* RFC9915 */
// Option code 10 is unassigned.
- D6O_AUTH = 11, /* RFC8415 */
- D6O_UNICAST = 12, /* RFC8415 */
- D6O_STATUS_CODE = 13, /* RFC8415 */
- D6O_RAPID_COMMIT = 14, /* RFC8415 */
- D6O_USER_CLASS = 15, /* RFC8415 */
- D6O_VENDOR_CLASS = 16, /* RFC8415 */
- D6O_VENDOR_OPTS = 17, /* RFC8415 */
- D6O_INTERFACE_ID = 18, /* RFC8415 */
- D6O_RECONF_MSG = 19, /* RFC8415 */
- D6O_RECONF_ACCEPT = 20, /* RFC8415 */
+ D6O_AUTH = 11, /* RFC9915 */
+ D6O_UNICAST = 12, /* RFC9915 (deprecated) */
+ D6O_STATUS_CODE = 13, /* RFC9915 */
+ D6O_RAPID_COMMIT = 14, /* RFC9915 */
+ D6O_USER_CLASS = 15, /* RFC9915 */
+ D6O_VENDOR_CLASS = 16, /* RFC9915 */
+ D6O_VENDOR_OPTS = 17, /* RFC9915 */
+ D6O_INTERFACE_ID = 18, /* RFC9915 */
+ D6O_RECONF_MSG = 19, /* RFC9915 */
+ D6O_RECONF_ACCEPT = 20, /* RFC9915 */
D6O_SIP_SERVERS_DNS = 21, /* RFC3319 */
D6O_SIP_SERVERS_ADDR = 22, /* RFC3319 */
D6O_NAME_SERVERS = 23, /* RFC3646 */
D6O_DOMAIN_SEARCH = 24, /* RFC3646 */
- D6O_IA_PD = 25, /* RFC8415, RFC3633 */
- D6O_IAPREFIX = 26, /* RFC8415, RFC3633 */
+ D6O_IA_PD = 25, /* RFC9915, RFC3633 */
+ D6O_IAPREFIX = 26, /* RFC9915, RFC3633 */
D6O_NIS_SERVERS = 27, /* RFC3898 */
D6O_NISP_SERVERS = 28, /* RFC3898 */
D6O_NIS_DOMAIN_NAME = 29, /* RFC3898 */
D6O_NISP_DOMAIN_NAME = 30, /* RFC3898 */
D6O_SNTP_SERVERS = 31, /* RFC4075 */
- D6O_INFORMATION_REFRESH_TIME = 32, /* RFC8415, RFC4242 */
+ D6O_INFORMATION_REFRESH_TIME = 32, /* RFC9915, RFC4242 */
D6O_BCMCS_SERVER_D = 33, /* RFC4280 */
D6O_BCMCS_SERVER_A = 34, /* RFC4280 */
// Option code 35 is unassigned.
D6O_CLIENT_LINKLAYER_ADDR = 79, /* RFC6939 */
D6O_LINK_ADDRESS = 80, /* RFC6977 */
// D6O_RADIUS = 81, /* RFC7037 */
- D6O_SOL_MAX_RT = 82, /* RFC8415, RFC7083 */
- D6O_INF_MAX_RT = 83, /* RFC8415, RFC7083 */
+ D6O_SOL_MAX_RT = 82, /* RFC9915, RFC7083 */
+ D6O_INF_MAX_RT = 83, /* RFC9915, RFC7083 */
// D6O_ADDRSEL = 84, /* RFC7078 */
// D6O_ADDRSEL_TABLE = 85, /* RFC7078 */
// D6O_V6_PCP_SERVER = 86, /* RFC7291 */
STATUS_NoAddrsAvail = 2,
STATUS_NoBinding = 3,
STATUS_NotOnLink = 4,
- STATUS_UseMulticast = 5,
+ STATUS_UseMulticast = 5, // deprecated
STATUS_NoPrefixAvail = 6,
STATUS_UnknownQueryType = 7,
STATUS_MalformedQuery = 8,
/// @brief minimum duid size
///
- /// The minimal DUID size specified in RFC 8415, section 11.1 is 3:
+ /// The minimal DUID size specified in RFC 9915, section 11.1 is 3:
/// 2 fixed octets for the type + 1 minimum octet for the value.
static constexpr size_t MIN_DUID_LEN = IdentifierType::getMinSize();
/// @brief maximum duid size
///
- /// The maximum DUID size specified in RFC 8415, section 11.1 is 130:
+ /// The maximum DUID size specified in RFC 9915, section 11.1 is 130:
/// 2 fixed octets for the type + 128 maximum octets for the value.
static constexpr size_t MAX_DUID_LEN = IdentifierType::getMaxSize();
/// @brief Factory for generating DUIDs (DHCP Unique Identifiers).
///
-/// DHCPv6 clients and servers are identified by DUIDs (see RFC 8415).
+/// DHCPv6 clients and servers are identified by DUIDs (see RFC 9915).
/// DUIDs are unique identifiers carried in the appropriate DHCP
-/// options. RFC 8415 defines 4 types of DUIDs:
+/// options. RFC 9915 defines 4 types of DUIDs:
/// -# DUID-LLT
/// -# DUID-EN
/// -# DUID-LL
///
/// of which the DUID-LLT is recommended for all general purpose computing
/// devices. Future specifications may define new DUID types. The current
-/// implementation of the class only supports DUID types defined in RFC 8415.
+/// implementation of the class only supports DUID types defined in RFC 9915.
///
/// In most cases DUIDs can be generated automatically, i.e. no manual
/// configuration is required. For example, DUID-LLT is composed of the
/// @brief Packet reception buffer size
///
- /// RFC 8415 states that server responses may be
+ /// RFC 9915 states that server responses may be
/// fragmented if they are over MTU. There is no
/// text whether client's packets may be larger
/// than 1500. For now, we can assume that
///
/// Authentication domain name field of variable length holding
/// a fully qualified domain name of the encrypted DNS resolver.
- /// This field is formatted as specified in Section 10 of RFC8415.
+ /// This field is formatted as specified in Section 10 of RFC9915.
boost::shared_ptr<isc::dns::Name> adn_;
/// @brief Length of all following data inside this DNR instance in octets.
/// @brief This class represents Authentication (11) DHCPv6 option.
///
-/// For details, see RFC 8415 Section 21.11.
+/// For details, see RFC 9915 Section 21.11.
class Option6Auth: public Option {
public:
/// @brief Pointer to the @c isc::dhcp::Option6StatusCode.
typedef boost::shared_ptr<Option6StatusCode> Option6StatusCodePtr;
-/// @brief This class represents Status Code option (13) from RFC 8415.
+/// @brief This class represents Status Code option (13) from RFC 9915.
class Option6StatusCode: public Option {
public:
/// @brief Constructor, used for options constructed (during transmission).
/// this is a single value the option type points to the data type of the
/// value. For example, DHCPv6 option 8 comprises a two-byte option code, a
/// two-byte option length and two-byte field that carries a uint16 value
-/// (RFC 8415 - http://ietf.org/rfc/rfc8415.txt). In such a case, the option
+/// (RFC 9915 - http://ietf.org/rfc/rfc9915.txt). In such a case, the option
/// type is defined as "uint16". Length and string tuples are a length
/// on one (DHCPv4) or two (DHCPv6) bytes followed by a string of
/// the given length.
///
/// Array types should be used when the option contains multiple contiguous
/// data values of the same type laid. For example, DHCPv6 option 6 includes
-/// multiple fields holding uint16 codes of requested DHCPv6 options (RFC 8415).
+/// multiple fields holding uint16 codes of requested DHCPv6 options (RFC 9915).
/// Such an option can be represented with this class by setting the option
/// type to "uint16" and the array indicator (array_type) to true. The number
/// of elements in the array is effectively unlimited (although it is actually
/// This class extends the base class with the support for enterprise numbers.
/// The enterprise numbers are assigned by IANA to various organizations
/// and they are carried as uint32_t integers in DHCPv6 Vendor Specific
-/// Information Options (VSIO). For more information refer to RFC 8415.
+/// Information Options (VSIO). For more information refer to RFC 9915.
/// All option spaces that group VSIO options must have enterprise number
/// set. It can be set using a constructor or \ref setVendorSpace function.
/// The extra functionality of this class (enterprise numbers) allows to
/// Class options.
///
/// The format of DHCPv6 Vendor Class option (16) is described in section 21.16
-/// of RFC 8415 and the format of the DHCPv4 V-I Vendor Class option (124) is
+/// of RFC 9915 and the format of the DHCPv4 V-I Vendor Class option (124) is
/// described in section 3 of RFC3925. Each of these options carries enterprise
/// id followed by the collection of tuples carrying opaque data. A single tuple
/// consists of the field holding opaque data length and the actual data.
///
/// For DHCPv6, The Vendor Class option mandates a 2-byte
/// OPTION_VENDOR_CLASS followed by a 2-byte option-len with a 4-byte
- /// enterprise-number. While section 21.16 of RFC 8415 specifies that the
+ /// enterprise-number. While section 21.16 of RFC 9915 specifies that the
/// information contained within the data area can contain one or more
/// opaque fields, the inclusion of the vendor-class-data is not mandatory
/// and therefore not factored into the overall possible minimum length.
// Now for each relay, we need to...
for (auto const& relay : relay_info_) {
- // build relay-forw/relay-repl header (see RFC 8415, section 9)
+ // build relay-forw/relay-repl header (see RFC 9915, section 9)
buffer_out_.writeUint8(relay.msg_type_);
buffer_out_.writeUint8(relay.hop_count_);
buffer_out_.writeData(&(relay.linkaddr_.toBytes()[0]),
/// The DHCPv6 server uses DHCPv6 Unique Identifier (DUID) to identify itself
/// to the clients. Typically, the server generates the DUID on the first
/// startup and writes it to the persistent storage so as it doesn't change
-/// across restarts of the server. RFC 8415 defines different DUID types.
+/// across restarts of the server. RFC 9915 defines different DUID types.
/// Kea allows for selecting a type of DUID that the server should generate.
/// It also allows for overriding entire default DUID or parts of it via
/// configuration file. This class holds the DUID configuration specified
populateFreeAddressLeases(leases4, pools);
break;
case Lease::TYPE_NA:
- case Lease::TYPE_TA:
leases6 = LeaseMgrFactory::instance().getLeases6(subnet->getID());
populateFreeAddressLeases(leases6, pools);
break;
///
/// key is a 16 byte value to be used in the authentication field.
/// Server replies will contain the below key in authentication field
- /// as specified in the RFC 8415. While sending reconfigure message
+ /// as specified in the RFC 9915. While sending reconfigure message
/// authentication field shall contain MD5 hash computed using this key.
AuthKey key_;
};
return string("V4");
case Lease::TYPE_NA:
return string("IA_NA");
- case Lease::TYPE_TA:
- return string("IA_TA");
case Lease::TYPE_PD:
return string("IA_PD");
break;
} else if (text == "IA_NA") {
return (TYPE_NA);
- } else if (text == "IA_TA") {
- return (TYPE_TA);
-
} else if (text == "IA_PD") {
return (TYPE_PD);
}
/// @brief Type of lease or pool
enum Type : uint16_t {
TYPE_NA = 0, ///< the lease contains non-temporary IPv6 address
- TYPE_TA = 1, ///< the lease contains temporary IPv6 address
+ TYPE_TA = 1, ///< deprecated (temporary IPv6 address)
TYPE_PD = 2, ///< the lease contains IPv6 prefix (for prefix delegation)
TYPE_V4 = 3, ///< IPv4 lease
};
break;
default:
- // We don't support TYPE_TAs yet
break;
}
}
break;
default:
- // We don't support TYPE_TAs yet
break;
}
}
@subsection allocEngineTypes Different lease types support
Allocation Engine has been extended to support different types of leases. Four
-types are supported: TYPE_V4 (IPv4 addresses), TYPE_NA (normal IPv6 addresses),
-TYPE_TA (temporary IPv6 addresses) and TYPE_PD (delegated prefixes). Support for
-TYPE_TA is partial. Some routines are able to handle it, while other are
+types are supported: TYPE_V4 (IPv4 addresses), TYPE_NA (normal IPv6 addresses)
+and TYPE_PD (delegated prefixes).
+Some routines are able to handle it, while other are
not. The major missing piece is the RandomAllocator, so there is no way to randomly
generate an address. This defeats the purpose of using temporary addresses for now.
isc_throw(BadValue, "Invalid Pool6 address boundaries: not IPv6");
}
- if ((type != Lease::TYPE_NA) && (type != Lease::TYPE_TA) &&
- (type != Lease::TYPE_PD)) {
+ if ((type != Lease::TYPE_NA) && (type != Lease::TYPE_PD)) {
isc_throw(BadValue, "Invalid Pool6 type: " << static_cast<int>(type)
- << ", must be TYPE_IA, TYPE_TA or TYPE_PD");
+ << ", must be TYPE_IA or TYPE_PD");
}
if (last < first) {
}
// TYPE_PD is not supported by this constructor. first-last style
- // parameters are for IA and TA only. There is another dedicated
+ // parameters are for NA only. There is another dedicated
// constructor for that (it uses prefix/length)
- if ((type != Lease::TYPE_NA) && (type != Lease::TYPE_TA)) {
+ if (type != Lease::TYPE_NA) {
isc_throw(BadValue, "Invalid Pool6 type specified: "
<< static_cast<int>(type));
}
break;
}
- case Lease::TYPE_NA:
- case Lease::TYPE_TA:{
+ case Lease::TYPE_NA:{
auto free_lease = LeaseMgrFactory::instance()
.sflqPickFreeLease6(pool->getFirstAddress(),
pool->getLastAddress());
case Lease::TYPE_PD:
isc_throw(Unexpected, "pickAddressInternal called for Lease::TYPE_PD");
break;
+ default:
+ isc_throw(Unexpected, "pickAddressInternal called for unknown lease type " << pool_type_);
+ break;
}
// Remove the exhausted pool from the list then try another one.
PoolPtr const pool = available[offset];
switch(pool_type_) {
case Lease::TYPE_V4:
- isc_throw(Unexpected, "pickAddressInternal called for Lease::TYPE_V4");
+ isc_throw(Unexpected, "pickPrefixInternal called for Lease::TYPE_V4");
break;
case Lease::TYPE_NA:
- case Lease::TYPE_TA:
- isc_throw(Unexpected, "pickAddressInternal called for Lease::TYPE_NA");
+ isc_throw(Unexpected, "pickPrefixInternal called for Lease::TYPE_NA");
break;
- case Lease::TYPE_PD:
+ case Lease::TYPE_PD:{
// Ask the lease manager for a lease from the pool.
auto free_lease = LeaseMgrFactory::instance()
.sflqPickFreeLease6(pool->getFirstAddress(),
getSubnetState()->setLastAllocatedTime();
return (free_lease);
}
-
+ }
+ break;
+ default:
+ isc_throw(Unexpected, "pickPrefixInternal called for unknown lease type " << pool_type_);
break;
}
case Lease::TYPE_V4:
case Lease::TYPE_NA:
return sumPoolCapacity(pools_);
- case Lease::TYPE_TA:
- return sumPoolCapacity(pools_ta_);
case Lease::TYPE_PD:
return sumPoolCapacity(pools_pd_);
default:
case Lease::TYPE_V4:
case Lease::TYPE_NA:
return sumPoolCapacity(pools_, client_classes);
- case Lease::TYPE_TA:
- return sumPoolCapacity(pools_ta_, client_classes);
case Lease::TYPE_PD:
return sumPoolCapacity(pools_pd_, client_classes);
default:
case Lease::TYPE_V4:
case Lease::TYPE_NA:
return sumPoolCapacity(pools_, client_classes);
- case Lease::TYPE_TA:
- return sumPoolCapacity(pools_ta_, client_classes);
case Lease::TYPE_PD:
return sumPoolCapacity(pools_pd_, client_classes, prefix_length_match,
hint_prefix_length);
case Lease::TYPE_V4:
case Lease::TYPE_NA:
return (pools_);
- case Lease::TYPE_TA:
- return (pools_ta_);
case Lease::TYPE_PD:
return (pools_pd_);
default:
case Lease::TYPE_V4:
case Lease::TYPE_NA:
return (pools_);
- case Lease::TYPE_TA:
- return (pools_ta_);
case Lease::TYPE_PD:
return (pools_pd_);
default:
} else {
overlaps =
poolOverlaps(Lease::TYPE_NA, pool) ||
- poolOverlaps(Lease::TYPE_PD, pool) ||
- poolOverlaps(Lease::TYPE_TA, pool);
+ poolOverlaps(Lease::TYPE_PD, pool);
}
if (overlaps) {
}
void Subnet6::checkType(Lease::Type type) const {
- if ((type != Lease::TYPE_NA) && (type != Lease::TYPE_TA) && (type != Lease::TYPE_PD)) {
+ if ((type != Lease::TYPE_NA) && (type != Lease::TYPE_PD)) {
isc_throw(BadValue, "Invalid Pool type: " << Lease::typeToText(type)
<< "(" << static_cast<int>(type)
- << "), must be TYPE_NA, TYPE_TA or TYPE_PD for Subnet6");
+ << "), must be TYPE_NA or TYPE_PD for Subnet6");
}
}
setAllocator(Lease::TYPE_NA,
boost::make_shared<RandomAllocator>
(Lease::TYPE_NA, shared_from_this()));
- setAllocator(Lease::TYPE_TA,
- boost::make_shared<RandomAllocator>
- (Lease::TYPE_TA, shared_from_this()));
setAllocationState(Lease::TYPE_NA, SubnetAllocationStatePtr());
- setAllocationState(Lease::TYPE_TA, SubnetAllocationStatePtr());
} else if (allocator_type == "flq") {
isc_throw(BadValue, "Free Lease Queue allocator is not supported for IPv6 address pools");
boost::make_shared<IterativeAllocator>
(Lease::TYPE_NA, shared_from_this()));
setAllocationState(Lease::TYPE_NA, SubnetIterativeAllocationState::create(shared_from_this()));
- setAllocationState(Lease::TYPE_TA, SubnetIterativeAllocationState::create(shared_from_this()));
}
auto pd_allocator_type = getPdAllocatorType();
pool->setAllocationState(PoolIterativeAllocationState::create(pool));
}
}
- // Create allocation states for TA pools.
- for (auto const& pool : pools_ta_) {
- if (allocator_type == "random") {
- pool->setAllocationState(PoolRandomAllocationState::create(pool));
- } else {
- pool->setAllocationState(PoolIterativeAllocationState::create(pool));
- }
- }
// Create allocation states for PD pools.
for (auto const& pool : pools_pd_) {
if (pd_allocator_type == "random") {
/// @brief collection of IPv4 or non-temporary IPv6 pools in that subnet.
PoolCollection pools_;
- /// @brief collection of IPv6 temporary address pools in that subnet.
- PoolCollection pools_ta_;
-
/// @brief collection of IPv6 prefix pools in that subnet.
PoolCollection pools_pd_;
EXPECT_EQ("", subnet->getDdnsConflictResolutionMode().get());
EXPECT_TRUE(subnet->getAllocationState(Lease::TYPE_NA));
- EXPECT_TRUE(subnet->getAllocationState(Lease::TYPE_TA));
EXPECT_TRUE(subnet->getAllocationState(Lease::TYPE_PD));
auto allocator = subnet->getAllocator(Lease::TYPE_NA);
EXPECT_TRUE(boost::dynamic_pointer_cast<IterativeAllocator>(allocator));
- allocator = subnet->getAllocator(Lease::TYPE_TA);
- EXPECT_TRUE(boost::dynamic_pointer_cast<IterativeAllocator>(allocator));
-
allocator = subnet->getAllocator(Lease::TYPE_PD);
EXPECT_TRUE(boost::dynamic_pointer_cast<IterativeAllocator>(allocator));
auto allocator = subnet->getAllocator(Lease::TYPE_NA);
ASSERT_TRUE(allocator);
EXPECT_TRUE(boost::dynamic_pointer_cast<RandomAllocator>(allocator));
- allocator = subnet->getAllocator(Lease::TYPE_TA);
- ASSERT_TRUE(allocator);
- EXPECT_TRUE(boost::dynamic_pointer_cast<RandomAllocator>(allocator));
// PD allocator should be iterative.
allocator = subnet->getAllocator(Lease::TYPE_PD);
ASSERT_TRUE(allocator);
auto allocator = subnet->getAllocator(Lease::TYPE_NA);
ASSERT_TRUE(allocator);
EXPECT_TRUE(boost::dynamic_pointer_cast<IterativeAllocator>(allocator));
- allocator = subnet->getAllocator(Lease::TYPE_TA);
- ASSERT_TRUE(allocator);
- EXPECT_TRUE(boost::dynamic_pointer_cast<IterativeAllocator>(allocator));
// PD allocator should be random.
allocator = subnet->getAllocator(Lease::TYPE_PD);
ASSERT_TRUE(allocator);
auto allocator = subnet->getAllocator(Lease::TYPE_NA);
ASSERT_TRUE(allocator);
EXPECT_TRUE(boost::dynamic_pointer_cast<IterativeAllocator>(allocator));
- allocator = subnet->getAllocator(Lease::TYPE_TA);
- ASSERT_TRUE(allocator);
- EXPECT_TRUE(boost::dynamic_pointer_cast<IterativeAllocator>(allocator));
// PD allocator should use FLQ.
allocator = subnet->getAllocator(Lease::TYPE_PD);
ASSERT_TRUE(allocator);
64, 1, 2, 3, 4, SubnetID(1));
auto state_na = boost::dynamic_pointer_cast<SubnetIterativeAllocationState>
(subnet->getAllocationState(Lease::TYPE_NA));
- auto state_ta = boost::dynamic_pointer_cast<SubnetIterativeAllocationState>
- (subnet->getAllocationState(Lease::TYPE_TA));
auto state_pd = boost::dynamic_pointer_cast<SubnetIterativeAllocationState>
(subnet->getAllocationState(Lease::TYPE_PD));
// Check initial conditions (all should be set to the last address in range)
EXPECT_EQ(last.toText(), state_na->getLastAllocated().toText());
- EXPECT_EQ(last.toText(), state_ta->getLastAllocated().toText());
EXPECT_EQ(last.toText(), state_pd->getLastAllocated().toText());
// Now set last allocated for IA
EXPECT_NO_THROW(state_na->setLastAllocated(na));
EXPECT_EQ(na.toText(), state_na->getLastAllocated().toText());
- // TA and PD should be unchanged
- EXPECT_EQ(last.toText(), state_ta->getLastAllocated().toText());
+ // PD should be unchanged
EXPECT_EQ(last.toText(), state_pd->getLastAllocated().toText());
- // Now set TA and PD
- EXPECT_NO_THROW(state_ta->setLastAllocated(ta));
+ // Now set PD
EXPECT_NO_THROW(state_pd->setLastAllocated(pd));
EXPECT_EQ(na.toText(), state_na->getLastAllocated().toText());
- EXPECT_EQ(ta.toText(), state_ta->getLastAllocated().toText());
EXPECT_EQ(pd.toText(), state_pd->getLastAllocated().toText());
}
64, 1, 2, 3, 4, SubnetID(1));
auto state_na = boost::dynamic_pointer_cast<SubnetIterativeAllocationState>
(subnet->getAllocationState(Lease::TYPE_NA));
- auto state_ta = boost::dynamic_pointer_cast<SubnetIterativeAllocationState>
- (subnet->getAllocationState(Lease::TYPE_TA));
auto state_pd = boost::dynamic_pointer_cast<SubnetIterativeAllocationState>
(subnet->getAllocationState(Lease::TYPE_PD));
// Check initial conditions (all should be set to the last address in range)
EXPECT_EQ(last.toText(), state_na->getLastAllocated().toText());
- EXPECT_EQ(last.toText(), state_ta->getLastAllocated().toText());
EXPECT_EQ(last.toText(), state_pd->getLastAllocated().toText());
// Now set last allocated for IA
EXPECT_NO_THROW(state_na->setLastAllocated(na));
EXPECT_EQ(na.toText(), state_na->getLastAllocated().toText());
- // TA and PD should be unchanged
- EXPECT_EQ(last.toText(), state_ta->getLastAllocated().toText());
+ // PD should be unchanged
EXPECT_EQ(last.toText(), state_pd->getLastAllocated().toText());
- // Now set TA and PD
- EXPECT_NO_THROW(state_ta->setLastAllocated(ta));
+ // Now set PD
EXPECT_NO_THROW(state_pd->setLastAllocated(pd));
EXPECT_EQ(na.toText(), state_na->getLastAllocated().toText());
- EXPECT_EQ(ta.toText(), state_ta->getLastAllocated().toText());
EXPECT_EQ(pd.toText(), state_pd->getLastAllocated().toText());
}
duid, iaid, 100, 200,
subnet_id, true, true, "", HWAddrPtr(), 96)),
BadValue, "prefixlen must be 128 for non prefix type");
-
- addr = IOAddress(ADDRESS[4]);
- EXPECT_THROW_MSG(lease2.reset(new Lease6(Lease::TYPE_TA, addr,
- duid, iaid, 100, 200,
- subnet_id, HWAddrPtr(), 96)),
- BadValue, "prefixlen must be 128 for non prefix type");
-
- EXPECT_THROW_MSG(lease2.reset(new Lease6(Lease::TYPE_TA, addr,
- duid, iaid, 100, 200,
- subnet_id, true, true, "", HWAddrPtr(), 96)),
- BadValue, "prefixlen must be 128 for non prefix type");
}
// This test verifies that the Lease6 constructor which accepts FQDN data,
BadValue);
}
-// Checks that temporary address pools are handled properly
-TEST(Pool6Test, TA) {
- // Note: since we defined TA pool types during PD work, we can test it
- // now. Although the configuration to take advantage of it is not
- // planned for now, we will support it some day.
-
- // Let's construct 2001:db8:1::/96 temporary addresses
- Pool6Ptr pool1;
- EXPECT_NO_THROW(pool1.reset(new Pool6(Lease::TYPE_TA,
- IOAddress("2001:db8:1::"), 96)));
-
- // Check that TA range can be only defined for single addresses
- EXPECT_THROW(Pool6(Lease::TYPE_TA, IOAddress("2001:db8:1::"), 96, 127),
- BadValue);
-
- ASSERT_TRUE(pool1);
- EXPECT_EQ(Lease::TYPE_TA, pool1->getType());
- EXPECT_EQ(128, pool1->getLength()); // singular addresses, not prefixes
- EXPECT_EQ("2001:db8:1::", pool1->getFirstAddress().toText());
- EXPECT_EQ("2001:db8:1::ffff:ffff", pool1->getLastAddress().toText());
-
- // Check that it's possible to have min-max range for TA
- Pool6Ptr pool2;
- EXPECT_NO_THROW(pool2.reset(new Pool6(Lease::TYPE_TA,
- IOAddress("2001:db8:1::1"),
- IOAddress("2001:db8:1::f"))));
- ASSERT_TRUE(pool2);
- EXPECT_EQ(Lease::TYPE_TA, pool2->getType());
- EXPECT_EQ(128, pool2->getLength()); // singular addresses, not prefixes
- EXPECT_EQ("2001:db8:1::1", pool2->getFirstAddress().toText());
- EXPECT_EQ("2001:db8:1::f", pool2->getLastAddress().toText());
-}
-
// Simple check if toText returns reasonable values
TEST(Pool6Test, toText) {
Pool6 pool1(Lease::TYPE_NA, IOAddress("2001:db8::1"),
for (unsigned i = 0; i < subnets.size(); ++i) {
preferred = network->getPreferredSubnet(subnets[i], Lease::TYPE_NA);
EXPECT_EQ(subnets[i]->getID(), preferred->getID());
- preferred = network->getPreferredSubnet(subnets[i], Lease::TYPE_TA);
- EXPECT_EQ(subnets[i]->getID(), preferred->getID());
preferred = network->getPreferredSubnet(subnets[i], Lease::TYPE_PD);
EXPECT_EQ(subnets[i]->getID(), preferred->getID());
}
for (unsigned i = 0; i < subnets.size(); ++i) {
preferred = network->getPreferredSubnet(subnets[i], Lease::TYPE_NA);
EXPECT_EQ(subnets[i]->getID(), preferred->getID());
- preferred = network->getPreferredSubnet(subnets[i], Lease::TYPE_TA);
- EXPECT_EQ(subnets[i]->getID(), preferred->getID());
preferred = network->getPreferredSubnet(subnets[i], Lease::TYPE_PD);
EXPECT_EQ(subnets[i]->getID(), preferred->getID());
}
for (unsigned i = 0; i < subnets.size(); ++i) {
preferred = network->getPreferredSubnet(subnets[i], Lease::TYPE_NA);
EXPECT_EQ(subnets[i]->getID(), preferred->getID());
- preferred = network->getPreferredSubnet(subnets[i], Lease::TYPE_TA);
- EXPECT_EQ(subnets[i]->getID(), preferred->getID());
preferred = network->getPreferredSubnet(subnets[i], Lease::TYPE_PD);
EXPECT_EQ(subnets[i]->getID(), preferred->getID());
}
PoolPtr pool1(new Pool4(IOAddress("192.2.1.0"), 24));
PoolPtr pool2(new Pool4(IOAddress("192.2.2.0"), 24));
PoolPtr pool3(new Pool6(Lease::TYPE_NA, IOAddress("2001:db8:1:3::"), 64));
- PoolPtr pool4(new Pool6(Lease::TYPE_TA, IOAddress("2001:db8:1:4::"), 64));
+ PoolPtr pool4(new Pool6(Lease::TYPE_NA, IOAddress("2001:db8:1:4::"), 64));
PoolPtr pool5(new Pool6(Lease::TYPE_PD, IOAddress("2001:db8:1:1::"), 64));
// There should be no pools of any type by default
// It should not be possible to ask for V6 pools in Subnet4
EXPECT_THROW(subnet->getAnyPool(Lease::TYPE_NA), BadValue);
- EXPECT_THROW(subnet->getAnyPool(Lease::TYPE_TA), BadValue);
EXPECT_THROW(subnet->getAnyPool(Lease::TYPE_PD), BadValue);
// Let's add a single V4 pool and check that it can be retrieved
PoolPtr pool3(new Pool6(Lease::TYPE_NA, IOAddress("2001:db8:1:3::"), 96));
EXPECT_EQ(0, subnet->getPoolCapacity(Lease::TYPE_NA));
- EXPECT_EQ(0, subnet->getPoolCapacity(Lease::TYPE_TA));
EXPECT_EQ(0, subnet->getPoolCapacity(Lease::TYPE_PD));
subnet->addPool(pool1);
PoolPtr pool3(new Pool6(Lease::TYPE_PD, IOAddress("2001:db8:3::"), 48, 80));
EXPECT_EQ(0, subnet->getPoolCapacity(Lease::TYPE_NA));
- EXPECT_EQ(0, subnet->getPoolCapacity(Lease::TYPE_TA));
EXPECT_EQ(0, subnet->getPoolCapacity(Lease::TYPE_PD));
subnet->addPool(pool1);
56, 1, 2, 3, 4, SubnetID(1));
PoolPtr pool1(new Pool6(Lease::TYPE_NA, IOAddress("2001:db8:1:1::"), 64));
- PoolPtr pool2(new Pool6(Lease::TYPE_TA, IOAddress("2001:db8:1:2::"), 64));
+ PoolPtr pool2(new Pool6(Lease::TYPE_NA, IOAddress("2001:db8:1:2::"), 64));
PoolPtr pool3(new Pool6(Lease::TYPE_PD, IOAddress("2001:db8:1:3::"), 64));
PoolPtr pool4(new Pool6(Lease::TYPE_PD, IOAddress("3000:1::"), 64));
// There should be no pools of any type by default
EXPECT_EQ(PoolPtr(), subnet->getAnyPool(Lease::TYPE_NA));
- EXPECT_EQ(PoolPtr(), subnet->getAnyPool(Lease::TYPE_TA));
EXPECT_EQ(PoolPtr(), subnet->getAnyPool(Lease::TYPE_PD));
// Trying to get IPv4 pool from Subnet6 is not allowed
EXPECT_EQ(pool1, subnet->getPool(Lease::TYPE_NA, IOAddress("2001:db8:1:1::1")));
// Check if pools of different type are not returned
- EXPECT_EQ(PoolPtr(), subnet->getAnyPool(Lease::TYPE_TA));
EXPECT_EQ(PoolPtr(), subnet->getAnyPool(Lease::TYPE_PD));
// We ask with good hints, but wrong types, should return nothing
EXPECT_EQ(PoolPtr(), subnet->getPool(Lease::TYPE_PD, IOAddress("2001:db8:1:2::1")));
- EXPECT_EQ(PoolPtr(), subnet->getPool(Lease::TYPE_TA, IOAddress("2001:db8:1:3::1")));
+ EXPECT_EQ(PoolPtr(), subnet->getPool(Lease::TYPE_PD, IOAddress("2001:db8:1:3::1")));
- // Let's add TA and PD pools
+ // Let's add second NA and first PD pools
EXPECT_NO_THROW(subnet->addPool(pool2));
EXPECT_NO_THROW(subnet->addPool(pool3));
// Try without hints
EXPECT_EQ(pool1, subnet->getAnyPool(Lease::TYPE_NA));
- EXPECT_EQ(pool2, subnet->getAnyPool(Lease::TYPE_TA));
EXPECT_EQ(pool3, subnet->getAnyPool(Lease::TYPE_PD));
// Try with valid hints
EXPECT_EQ(pool1, subnet->getPool(Lease::TYPE_NA, IOAddress("2001:db8:1:1::1")));
- EXPECT_EQ(pool2, subnet->getPool(Lease::TYPE_TA, IOAddress("2001:db8:1:2::1")));
+ EXPECT_EQ(pool2, subnet->getPool(Lease::TYPE_NA, IOAddress("2001:db8:1:2::1")));
EXPECT_EQ(pool3, subnet->getPool(Lease::TYPE_PD, IOAddress("2001:db8:1:3::1")));
// Try with bogus hints (hints should be ignored)
EXPECT_EQ(pool1, subnet->getPool(Lease::TYPE_NA, IOAddress("2001:db8:1:7::1")));
- EXPECT_EQ(pool2, subnet->getPool(Lease::TYPE_TA, IOAddress("2001:db8:1:7::1")));
EXPECT_EQ(pool3, subnet->getPool(Lease::TYPE_PD, IOAddress("2001:db8:1:7::1")));
// Let's add a second PD pool
// NA pool.
auto pool = boost::make_shared<Pool6>(Lease::TYPE_NA, IOAddress("2001:db8:1:1::"), 112);
subnet->addPool(pool);
- // TA pool.
- auto ta_pool = boost::make_shared<Pool6>(Lease::TYPE_TA, IOAddress("2001:db8:1:2::"), 112);
- subnet->addPool(ta_pool);
// PD pool.
auto pd_pool = boost::make_shared<Pool6>(Lease::TYPE_PD, IOAddress("3000::"), 112, 120);
subnet->addPool(pd_pool);
// Expect iterative allocator for NA.
EXPECT_TRUE(boost::dynamic_pointer_cast<IterativeAllocator>
(subnet->getAllocator(Lease::TYPE_NA)));
- // Expect iterative allocator for TA.
- EXPECT_TRUE(boost::dynamic_pointer_cast<IterativeAllocator>
- (subnet->getAllocator(Lease::TYPE_TA)));
// Expect iterative allocator for PD.
EXPECT_TRUE(boost::dynamic_pointer_cast<IterativeAllocator>
(subnet->getAllocator(Lease::TYPE_PD)));
// Expect iterative allocation state for NA.
EXPECT_TRUE(boost::dynamic_pointer_cast<SubnetIterativeAllocationState>
(subnet->getAllocationState(Lease::TYPE_NA)));
- // Expect iterative allocation state for TA.
- EXPECT_TRUE(boost::dynamic_pointer_cast<SubnetIterativeAllocationState>
- (subnet->getAllocationState(Lease::TYPE_TA)));
// Expect iterative allocation state for PD.
EXPECT_TRUE(boost::dynamic_pointer_cast<SubnetIterativeAllocationState>
(subnet->getAllocationState(Lease::TYPE_PD)));
// Expect iterative allocation state for the NA pool.
- EXPECT_TRUE(boost::dynamic_pointer_cast<PoolIterativeAllocationState>
- (pool->getAllocationState()));
- // Expect iterative allocation state for the TA pool.
EXPECT_TRUE(boost::dynamic_pointer_cast<PoolIterativeAllocationState>
(pool->getAllocationState()));
// Expect iterative allocation state for the PD pool.
// NA pool.
auto pool = boost::make_shared<Pool6>(Lease::TYPE_NA, IOAddress("2001:db8:1:1::"), 112);
subnet->addPool(pool);
- // TA pool.
- auto ta_pool = boost::make_shared<Pool6>(Lease::TYPE_TA, IOAddress("2001:db8:1:2::"), 112);
- subnet->addPool(ta_pool);
// PD pool.
auto pd_pool = boost::make_shared<Pool6>(Lease::TYPE_PD, IOAddress("3000::"), 112, 120);
subnet->addPool(pd_pool);
// Expect random allocator for NA.
EXPECT_TRUE(boost::dynamic_pointer_cast<RandomAllocator>
(subnet->getAllocator(Lease::TYPE_NA)));
- // Expect random allocator for TA.
- EXPECT_TRUE(boost::dynamic_pointer_cast<RandomAllocator>
- (subnet->getAllocator(Lease::TYPE_TA)));
// Expect random allocator for PD.
EXPECT_TRUE(boost::dynamic_pointer_cast<RandomAllocator>
(subnet->getAllocator(Lease::TYPE_PD)));
// Expect null subnet allocation state for NA.
EXPECT_FALSE(subnet->getAllocationState(Lease::TYPE_NA));
- // Expect null subnet allocation state for TA.
- EXPECT_FALSE(subnet->getAllocationState(Lease::TYPE_TA));
// Expect null subnet allocation state for PD.
EXPECT_FALSE(subnet->getAllocationState(Lease::TYPE_PD));
// Expect random allocation state for the NA pool.
// NA pool.
auto pool = boost::make_shared<Pool6>(Lease::TYPE_NA, IOAddress("2001:db8:1:1::"), 112);
subnet->addPool(pool);
- // TA pool.
- auto ta_pool = boost::make_shared<Pool6>(Lease::TYPE_TA, IOAddress("2001:db8:1:2::"), 112);
- subnet->addPool(ta_pool);
// PD pool.
auto pd_pool = boost::make_shared<Pool6>(Lease::TYPE_PD, IOAddress("3000::"), 112, 120);
subnet->addPool(pd_pool);
// Expect random allocator for NA.
EXPECT_TRUE(boost::dynamic_pointer_cast<RandomAllocator>
(subnet->getAllocator(Lease::TYPE_NA)));
- // Expect random allocator for TA.
- EXPECT_TRUE(boost::dynamic_pointer_cast<RandomAllocator>
- (subnet->getAllocator(Lease::TYPE_TA)));
// Expect FLQ allocator for PD.
EXPECT_TRUE(boost::dynamic_pointer_cast<FreeLeaseQueueAllocator>
(subnet->getAllocator(Lease::TYPE_PD)));
// Expect null subnet allocation state for NA.
EXPECT_FALSE(subnet->getAllocationState(Lease::TYPE_NA));
- // Expect null subnet allocation state for TA.
- EXPECT_FALSE(subnet->getAllocationState(Lease::TYPE_TA));
// Expect null subnet allocation state for PD.
EXPECT_FALSE(subnet->getAllocationState(Lease::TYPE_PD));
// Expect random allocation state for the NA pool.
- EXPECT_TRUE(boost::dynamic_pointer_cast<PoolRandomAllocationState>
- (pool->getAllocationState()));
- // Expect random allocation state for the TA pool.
EXPECT_TRUE(boost::dynamic_pointer_cast<PoolRandomAllocationState>
(pool->getAllocationState()));
// Expect FLQ allocation state for the PD pool.
EXPECT_TRUE(boost::dynamic_pointer_cast<PoolFreeLeaseQueueAllocationState>
- (pd_pool->getAllocationState()));
-}
+ (pd_pool->getAllocationState()));}
+
// Test that it is not allowed to use the FLQ allocator for the address pools.
TEST(Subnet6Test, createAllocatorsFreeLeaseQueueNotAllowed) {
// Lease types that correspond to ADDRESS6 leases
static const Lease::Type LEASETYPE6[] = {
- Lease::TYPE_NA, Lease::TYPE_TA, Lease::TYPE_PD, Lease::TYPE_NA,
- Lease::TYPE_TA, Lease::TYPE_PD, Lease::TYPE_NA, Lease::TYPE_TA
+ Lease::TYPE_NA, Lease::TYPE_PD, Lease::TYPE_NA, Lease::TYPE_PD,
+ Lease::TYPE_NA, Lease::TYPE_PD, Lease::TYPE_NA, Lease::TYPE_PD
};
GenericLeaseMgrTest::GenericLeaseMgrTest()
} else if (address == straddress6_[1]) {
lease->hwaddr_.reset(new HWAddr(vector<uint8_t>(6, 0x19), HTYPE_ETHER));
lease->type_ = leasetype6_[1];
- lease->prefixlen_ = 128;
+ lease->prefixlen_ = 48;
lease->iaid_ = 42;
lease->duid_ = DuidPtr(new DUID(vector<uint8_t>(8, 0x42)));
lease->preferred_lft_ = 3600;
} else if (address == straddress6_[2]) {
lease->hwaddr_.reset(new HWAddr(vector<uint8_t>(6, 0x2a), HTYPE_ETHER));
lease->type_ = leasetype6_[2];
- lease->prefixlen_ = 48;
+ lease->prefixlen_ = 128;
lease->iaid_ = 89;
lease->duid_ = DuidPtr(new DUID(vector<uint8_t>(8, 0x3a)));
lease->preferred_lft_ = 1800;
// Hardware address same as lease 1.
lease->hwaddr_.reset(new HWAddr(vector<uint8_t>(6, 0x19), HTYPE_ETHER));
lease->type_ = leasetype6_[3];
- lease->prefixlen_ = 128;
+ lease->prefixlen_ = 48;
lease->iaid_ = 0xfffffffe;
vector<uint8_t> duid;
for (uint8_t i = 31; i < 126; ++i) {
lease->hwaddr_.reset(new HWAddr(vector<uint8_t>(), HTYPE_ETHER)); // Empty
// Same IAID as straddress6_1
lease->type_ = leasetype6_[7];
- lease->prefixlen_ = 128;
+ lease->prefixlen_ = 56;
lease->iaid_ = 42;
lease->duid_ = DuidPtr(new DUID(vector<uint8_t>(8, 0xe5)));
lease->preferred_lft_ = 5600;
// Make Two leases per lease type, all with the same DUID, IAID but
// alternate the subnet_ids.
vector<Lease6Ptr> leases;
- for (int i = 0; i < 6; ++i) {
- if (i > 3) {
+ for (int i = 0; i < 4; ++i) {
+ if (i > 2) {
empty_lease->prefixlen_ = 48;
} else {
empty_lease->prefixlen_ = 128;
}
// Verify getting a single lease by type and address.
- for (int i = 0; i < 6; ++i) {
+ for (int i = 0; i < 4; ++i) {
// Look for exact match for each lease type.
Lease6Ptr returned = lmptr_->getLease6(leasetype6_[i / 2],
leases[i]->addr_);
// Verify getting a collection of leases by type, DUID, and IAID.
// Iterate over the lease types, asking for leases based on
// lease type, DUID, and IAID.
- for (size_t i = 0; i < 3; ++i) {
+ for (size_t i = 0; i < 2; ++i) {
Lease6Collection returned = lmptr_->getLeases6(leasetype6_[i], *duid, 142);
auto compare = [](const Lease6Ptr& left, const Lease6Ptr& right) {
// Verify getting a collection of leases by type, DUID, IAID, and subnet id.
// Iterate over the lease types, asking for leases based on
// lease type, DUID, IAID, and subnet_id.
- for (int i = 0; i < 3; ++i) {
+ for (int i = 0; i < 2; ++i) {
Lease6Collection returned = lmptr_->getLeases6(leasetype6_[i], *duid, 142, 23);
// We should match one per lease type.
ASSERT_EQ(1, returned.size());
}
// Verify getting a single lease by type, duid, iad, and subnet id.
- for (int i = 0; i < 6; ++i) {
+ for (int i = 0; i < 4; ++i) {
Lease6Ptr returned = lmptr_->getLease6(leasetype6_[i / 2], *duid, 142, (23 + (i % 2)));
// We should match one per lease type.
ASSERT_TRUE(returned);
// Alter the lease again and check.
++leases[1]->iaid_;
- leases[1]->type_ = Lease::TYPE_TA;
+ leases[1]->type_ = Lease::TYPE_NA;
leases[1]->cltt_ += 6;
leases[1]->prefixlen_ = 128;
leases[1]->setContext(Element::fromJSON("{ \"foo\": \"bar\" }"));
lmptr_->updateLease6(leases[1]);
l_returned.reset();
- l_returned = lmptr_->getLease6(Lease::TYPE_TA, ioaddress6_[1]);
+ l_returned = lmptr_->getLease6(Lease::TYPE_NA, ioaddress6_[1]);
ASSERT_TRUE(l_returned);
detailCompareLease(leases[1], l_returned);
// Check we can do an update without changing data.
lmptr_->updateLease6(leases[1]);
l_returned.reset();
- l_returned = lmptr_->getLease6(Lease::TYPE_TA, ioaddress6_[1]);
+ l_returned = lmptr_->getLease6(Lease::TYPE_NA, ioaddress6_[1]);
ASSERT_TRUE(l_returned);
detailCompareLease(leases[1], l_returned);