srv.classifyPacket(dis2);
- EXPECT_TRUE(dis2->inClass("eRouter1.0"));
- EXPECT_FALSE(dis2->inClass("docsis3.0"));
+ EXPECT_TRUE(dis2->inClass(srv.VENDOR_CLASS_PREFIX + "eRouter1.0"));
+ EXPECT_FALSE(dis2->inClass(srv.VENDOR_CLASS_PREFIX + "docsis3.0"));
}
+ // Checks if the client-class field is indeed used for subnet selection.
+ // Note that packet classification is already checked in Dhcpv4SrvTest
+ // .clientClassification above.
+ TEST_F(Dhcpv4SrvTest, clientClassify2) {
+
+ NakedDhcpv4Srv srv(0);
+
+ ConstElementPtr status;
+
+ // This test configures 2 subnets. We actually only need the
+ // first one, but since there's still this ugly hack that picks
+ // the pool if there is only one, we must use more than one
+ // subnet. That ugly hack will be removed in #3242, currently
+ // under review.
+
+ // The second subnet does not play any role here. The client's
+ // IP address belongs to the first subnet, so only that first
+ // subnet it being tested.
+ string config = "{ \"interfaces\": [ \"*\" ],"
+ "\"rebind-timer\": 2000, "
+ "\"renew-timer\": 1000, "
+ "\"subnet4\": [ "
+ "{ \"pool\": [ \"192.0.2.1 - 192.0.2.100\" ],"
+ " \"client-class\": \"foo\", "
+ " \"subnet\": \"192.0.2.0/24\" }, "
+ "{ \"pool\": [ \"192.0.3.1 - 192.0.3.100\" ],"
+ " \"client-class\": \"xyzzy\", "
+ " \"subnet\": \"192.0.3.0/24\" } "
+ "],"
+ "\"valid-lifetime\": 4000 }";
+
+ ElementPtr json = Element::fromJSON(config);
+
+ EXPECT_NO_THROW(status = configureDhcp4Server(srv, json));
+
+ // check if returned status is OK
+ ASSERT_TRUE(status);
+ comment_ = config::parseAnswer(rcode_, status);
+ ASSERT_EQ(0, rcode_);
+
+ 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);
+
+ // This discover does not belong to foo class, so it will not
+ // be serviced
+ EXPECT_FALSE(srv.selectSubnet(dis));
+
+ // Let's add the packet to bar class and try again.
+ dis->addClass("bar");
+
+ // Still not supported, because it belongs to wrong class.
+ EXPECT_FALSE(srv.selectSubnet(dis));
+
+ // Let's add it to maching class.
+ dis->addClass("foo");
+
+ // This time it should work
+ EXPECT_TRUE(srv.selectSubnet(dis));
+ }
+
// This test verifies that the direct message is dropped when it has been
// received by the server via an interface for which there is no subnet
// configured. It also checks that the message is not dropped (is processed)
srv.classifyPacket(sol2);
- EXPECT_TRUE(sol2->inClass("eRouter1.0"));
- EXPECT_FALSE(sol2->inClass("docsis3.0"));
+ EXPECT_TRUE(sol2->inClass(srv.VENDOR_CLASS_PREFIX + "eRouter1.0"));
+ EXPECT_FALSE(sol2->inClass(srv.VENDOR_CLASS_PREFIX + "docsis3.0"));
}
+ // Checks if the client-class field is indeed used for subnet selection.
+ // Note that packet classification is already checked in Dhcpv6SrvTest
+ // .clientClassification above.
+ TEST_F(Dhcpv6SrvTest, clientClassify2) {
+
+ NakedDhcpv6Srv srv(0);
+
+ ConstElementPtr status;
+
+ // This test configures 2 subnets. We actually only need the
+ // first one, but since there's still this ugly hack that picks
+ // the pool if there is only one, we must use more than one
+ // subnet. That ugly hack will be removed in #3242, currently
+ // under review.
+
+ // The second subnet does not play any role here. The client's
+ // IP address belongs to the first subnet, so only that first
+ // subnet it being tested.
+ string config = "{ \"interfaces\": [ \"*\" ],"
+ "\"preferred-lifetime\": 3000,"
+ "\"rebind-timer\": 2000, "
+ "\"renew-timer\": 1000, "
+ "\"subnet6\": [ "
+ " { \"pool\": [ \"2001:db8:1::/64\" ],"
+ " \"subnet\": \"2001:db8:1::/48\", "
+ " \"client-class\": \"foo\" "
+ " }, "
+ " { \"pool\": [ \"2001:db8:2::/64\" ],"
+ " \"subnet\": \"2001:db8:2::/48\", "
+ " \"client-class\": \"xyzzy\" "
+ " } "
+ "],"
+ "\"valid-lifetime\": 4000 }";
+
+ ElementPtr json = Element::fromJSON(config);
+
+ EXPECT_NO_THROW(status = configureDhcp6Server(srv, json));
+
+ // check if returned status is OK
+ ASSERT_TRUE(status);
+ comment_ = config::parseAnswer(rcode_, status);
+ ASSERT_EQ(0, rcode_);
+
+ Pkt6Ptr sol = Pkt6Ptr(new Pkt6(DHCPV6_SOLICIT, 1234));
+ sol->setRemoteAddr(IOAddress("2001:db8:1::3"));
+ sol->addOption(generateIA(D6O_IA_NA, 234, 1500, 3000));
+ OptionPtr clientid = generateClientId();
+ sol->addOption(clientid);
+
+ // This discover does not belong to foo class, so it will not
+ // be serviced
+ EXPECT_FALSE(srv.selectSubnet(sol));
+
+ // Let's add the packet to bar class and try again.
+ sol->addClass("bar");
+
+ // Still not supported, because it belongs to wrong class.
+ EXPECT_FALSE(srv.selectSubnet(sol));
+
+ // Let's add it to maching class.
+ sol->addClass("foo");
+
+ // This time it should work
+ EXPECT_TRUE(srv.selectSubnet(sol));
+ }
+
+// This test checks that the server will handle a Solicit with the Vendor Class
+// having a length of 4 (enterprise-id only).
+TEST_F(Dhcpv6SrvTest, cableLabsShortVendorClass) {
+ NakedDhcpv6Srv srv(0);
+
+ // Create a simple Solicit with the 4-byte long vendor class option.
+ Pkt6Ptr sol = captureCableLabsShortVendorClass();
+
+ // Simulate that we have received that traffic
+ srv.fakeReceive(sol);
+
+ // Server will now process to run its normal loop, but instead of calling
+ // IfaceMgr::receive6(), it will read all packets from the list set by
+ // fakeReceive()
+ srv.run();
+
+ // Get Advertise...
+ ASSERT_FALSE(srv.fake_sent_.empty());
+ Pkt6Ptr adv = srv.fake_sent_.front();
+ ASSERT_TRUE(adv);
+
+ // This is sent back to client, so port is 546
+ EXPECT_EQ(DHCP6_CLIENT_PORT, adv->getRemotePort());
+
+}
/// @todo: Add more negative tests for processX(), e.g. extend sanityCheck() test
/// to call processX() methods.
// see wireshark.cc for descriptions
// The descriptions are too large and too closely related to the
// code, so it is kept in .cc rather than traditionally in .h
- Pkt6Ptr captureSimpleSolicit();
- Pkt6Ptr captureRelayedSolicit();
- Pkt6Ptr captureDocsisRelayedSolicit();
- Pkt6Ptr captureeRouterRelayedSolicit();
- Pkt6Ptr captureCableLabsShortVendorClass();
+ isc::dhcp::Pkt6Ptr captureSimpleSolicit();
+ isc::dhcp::Pkt6Ptr captureRelayedSolicit();
+ isc::dhcp::Pkt6Ptr captureDocsisRelayedSolicit();
+ isc::dhcp::Pkt6Ptr captureeRouterRelayedSolicit();
++ isc::dhcp::Pkt6Ptr captureCableLabsShortVendorClass();
/// @brief Auxiliary method that sets Pkt6 fields
///