#include <dhcp/option6_iaaddr.h>
#include <dhcp/option6_status_code.h>
#include <dhcp/option_int_array.h>
+ #include <dhcp/option_vendor.h>
#include <dhcp/pkt6.h>
#include <dhcpsrv/lease.h>
+#include <dhcpsrv/pool.h>
#include <dhcp6/tests/dhcp6_client.h>
#include <util/buffer.h>
#include <boost/foreach.hpp>
link_local_("fe80::3a60:77ff:fed5:cdef"),
iface_name_("eth0"),
srv_(boost::shared_ptr<NakedDhcpv6Srv>(new NakedDhcpv6Srv(0))),
- use_na_(false),
- use_pd_(false),
use_relay_(false),
use_oro_(false),
+ use_docsis_oro_(false),
use_client_id_(true),
use_rapid_commit_(false),
- address_hint_(),
- prefix_hint_(),
- fqdn_(),
- na_iaid_(1234),
- pd_iaid_(5678),
- include_address_(true) {
+ client_ias_(),
+ fqdn_() {
}
Dhcp6Client::Dhcp6Client(boost::shared_ptr<NakedDhcpv6Srv>& srv) :
link_local_("fe80::3a60:77ff:fed5:cdef"),
iface_name_("eth0"),
srv_(srv),
- use_na_(false),
- use_pd_(false),
use_relay_(false),
use_oro_(false),
+ use_docsis_oro_(false),
use_client_id_(true),
use_rapid_commit_(false),
- address_hint_(),
- prefix_hint_(),
- fqdn_(),
- na_iaid_(1234),
- pd_iaid_(5678),
- include_address_(true) {
+ client_ias_(),
+ fqdn_() {
}
void
EXPECT_EQ(STATUS_Success, client.getStatusCode(1234));
}
- client.useNA();
+ // This test verifies that the client can request the DOCSIS sub-options.
+ TEST_F(RebindTest, docsisORO) {
+ Dhcp6Client client;
+ // Configure client to request IA_NA.
++ client.requestAddress();
+ // Configure the DOCSIS vendor ORO for 32, 33, 34, 37 and 38.
+ client.requestDocsisOption(DOCSIS3_V6_TFTP_SERVERS);
+ client.requestDocsisOption(DOCSIS3_V6_CONFIG_FILE);
+ client.requestDocsisOption(DOCSIS3_V6_SYSLOG_SERVERS);
+ client.requestDocsisOption(DOCSIS3_V6_TIME_SERVERS);
+ client.requestDocsisOption(DOCSIS3_V6_TIME_OFFSET);
+ // Don't add it for now.
+ client.useDocsisORO(false);
+ // Make 4-way exchange to get the lease.
+ ASSERT_NO_FATAL_FAILURE(requestLease(REBIND_CONFIGS[7], 2, client));
+ // Keep the client's lease for future reference.
+ Lease6 lease_client = client.getLease(0);
+
+ // Send Rebind message to the server.
+ ASSERT_NO_THROW(client.doRebind());
+ // The client should still have one lease which belong to one of the
+ // subnets.
+ ASSERT_EQ(1, client.getLeaseNum());
+ Lease6 lease_client2 = client.getLease(0);
+ ASSERT_TRUE(CfgMgr::instance().getCurrentCfg()->getCfgSubnets6()->
+ selectSubnet(lease_client2.addr_, ClientClasses()));
+ // The client's lease should have been extended. The client will
+ // update the cltt to current time when the lease gets extended.
+ ASSERT_GE(lease_client2.cltt_ - lease_client.cltt_, 1000);
+ // Make sure, that the client's lease matches the lease held by the
+ // server.
+ Lease6Ptr lease_server2 = checkLease(lease_client2);
+ EXPECT_TRUE(lease_server2);
+ // No vendor option was included in the renew so there should be none
+ // in the received configuration.
+ OptionPtr opt = client.config_.findOption(D6O_VENDOR_OPTS);
+ ASSERT_FALSE(opt);
+
+ // Add a DOCSIS ORO.
+ client.useDocsisORO(true);
+ // Send Rebind message to the server.
+ ASSERT_NO_THROW(client.doRebind());
+ // The client should still have one lease which belong to one of the
+ // subnets.
+ ASSERT_EQ(1, client.getLeaseNum());
+ lease_client2 = client.getLease(0);
+ ASSERT_TRUE(CfgMgr::instance().getCurrentCfg()->getCfgSubnets6()->
+ selectSubnet(lease_client2.addr_, ClientClasses()));
+ // The client's lease should have been extended. The client will
+ // update the cltt to current time when the lease gets extended.
+ ASSERT_GE(lease_client2.cltt_ - lease_client.cltt_, 1000);
+ // Make sure, that the client's lease matches the lease held by the
+ // server.
+ lease_server2 = checkLease(lease_client2);
+ EXPECT_TRUE(lease_server2);
+
+ // Verify whether there is a vendor option.
+ opt = client.config_.findOption(D6O_VENDOR_OPTS);
+ ASSERT_TRUE(opt);
+ // The vendor option must be a OptionVendor object.
+ boost::shared_ptr<OptionVendor> vendor =
+ boost::dynamic_pointer_cast<OptionVendor>(opt);
+ ASSERT_TRUE(vendor);
+ // The vendor-id should be DOCSIS.
+ EXPECT_EQ(VENDOR_ID_CABLE_LABS, vendor->getVendorId());
+ // There must be a config file sub-option.
+ opt = vendor->getOption(DOCSIS3_V6_CONFIG_FILE);
+ // With the expected content.
+ OptionStringPtr config_file =
+ boost::dynamic_pointer_cast<OptionString>(opt);
+ ASSERT_TRUE(opt);
+ EXPECT_EQ("normal_erouter_v6.cm", config_file->getValue());
+ }
} // end of anonymous namespace
EXPECT_EQ(STATUS_Success, client.getStatusCode(na_iaid_));
}
- client.useNA(na_iaid_);
+ // This test verifies that the client can request the DOCSIS sub-options.
+ TEST_F(RenewTest, docsisORO) {
+ Dhcp6Client client;
+
+ // Configure client to request IA_NA.
++ client.requestAddress(na_iaid_);
+
+ // Configure the DOCSIS vendor ORO for 32, 33, 34, 37 and 38.
+ client.requestDocsisOption(DOCSIS3_V6_TFTP_SERVERS);
+ client.requestDocsisOption(DOCSIS3_V6_CONFIG_FILE);
+ client.requestDocsisOption(DOCSIS3_V6_SYSLOG_SERVERS);
+ client.requestDocsisOption(DOCSIS3_V6_TIME_SERVERS);
+ client.requestDocsisOption(DOCSIS3_V6_TIME_OFFSET);
+ // Don't add it for now.
+ client.useDocsisORO(false);
+
+ // Configure the server with NA pools and DOCSIS config file.
+ ASSERT_NO_THROW(configure(RENEW_CONFIGS[3], *client.getServer()));
+
+ // Perform 4-way exchange.
+ ASSERT_NO_THROW(client.doSARR());
+
+ // Simulate aging of leases.
+ client.fastFwdTime(1000);
+
+ // Make sure that the client has acquired NA lease.
+ std::vector<Lease6> leases_client_na = client.getLeasesByType(Lease::TYPE_NA);
+ ASSERT_EQ(1, leases_client_na.size());
+ EXPECT_EQ(STATUS_Success, client.getStatusCode(na_iaid_));
+
+ // Send Renew message to the server.
+ ASSERT_NO_THROW(client.doRenew());
+
+ std::vector<Lease6> leases_client_na_renewed =
+ client.getLeasesByType(Lease::TYPE_NA);
+ ASSERT_EQ(1, leases_client_na_renewed.size());
+ EXPECT_EQ(STATUS_Success, client.getStatusCode(na_iaid_));
+
+ // No vendor option was included in the renew so there should be none
+ // in the received configuration.
+ OptionPtr opt = client.config_.findOption(D6O_VENDOR_OPTS);
+ ASSERT_FALSE(opt);
+
+ // Add a DOCSIS ORO.
+ client.useDocsisORO(true);
+
+ // Send Renew message to the server.
+ ASSERT_NO_THROW(client.doRenew());
+
+ leases_client_na_renewed = client.getLeasesByType(Lease::TYPE_NA);
+ ASSERT_EQ(1, leases_client_na_renewed.size());
+ EXPECT_EQ(STATUS_Success, client.getStatusCode(na_iaid_));
+
+ // Verify whether there is a vendor option.
+ opt = client.config_.findOption(D6O_VENDOR_OPTS);
+ ASSERT_TRUE(opt);
+
+ // The vendor option must be a OptionVendor object.
+ boost::shared_ptr<OptionVendor> vendor =
+ boost::dynamic_pointer_cast<OptionVendor>(opt);
+ ASSERT_TRUE(vendor);
+
+ // The vendor-id should be DOCSIS.
+ EXPECT_EQ(VENDOR_ID_CABLE_LABS, vendor->getVendorId());
+
+ // There must be a config file sub-option.
+ opt = vendor->getOption(DOCSIS3_V6_CONFIG_FILE);
+
+ // With the expected content.
+ OptionStringPtr config_file =
+ boost::dynamic_pointer_cast<OptionString>(opt);
+ ASSERT_TRUE(opt);
+ EXPECT_EQ("normal_erouter_v6.cm", config_file->getValue());
+ }
} // end of anonymous namespace