BIND 10 pd-ietf-demo, updated. 58f0f8eb613241b74acd1cf125a032aad756fbed [pd-ietf-demo] Merge branch 'trac3203' into pd-ietf-demo
BIND 10 source code commits
bind10-changes at lists.isc.org
Fri Oct 18 09:21:44 UTC 2013
The branch, pd-ietf-demo has been updated
via 58f0f8eb613241b74acd1cf125a032aad756fbed (commit)
via c5e286f1fdaef8bde35951ca0b2a8947654c9095 (commit)
via edc603c54d0da5cdff12a67d9b2f993d5705570f (commit)
via bdc703178e699d643504b21c6a754345e821b8ed (commit)
from f852ddb9defdd0ccc930b96eb5df406739f07ea2 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commit 58f0f8eb613241b74acd1cf125a032aad756fbed
Merge: f852ddb c5e286f
Author: Tomek Mrugalski <tomasz at isc.org>
Date: Fri Oct 18 11:21:29 2013 +0200
[pd-ietf-demo] Merge branch 'trac3203' into pd-ietf-demo
Conflicts:
src/bin/dhcp4/dhcp4_srv.cc
src/lib/dhcp/dhcp4.h
-----------------------------------------------------------------------
Summary of changes:
src/bin/dhcp4/dhcp4_messages.mes | 8 +++
src/bin/dhcp4/dhcp4_srv.cc | 77 +++++++++++++++++++++++++++++
src/bin/dhcp4/dhcp4_srv.h | 13 +++++
src/bin/dhcp4/tests/dhcp4_srv_unittest.cc | 29 +++++++++++
src/bin/dhcp4/tests/dhcp4_test_utils.h | 12 ++++-
src/bin/dhcp4/tests/wireshark.cc | 60 +++++++++++++++++++++-
src/lib/dhcp/pkt4.cc | 12 +++++
src/lib/dhcp/pkt4.h | 25 ++++++++++
src/lib/dhcp/pkt6.cc | 11 +++++
src/lib/dhcp/pkt6.h | 25 ++++++++++
src/lib/dhcp/std_option_defs.h | 2 +-
src/lib/dhcp/tests/libdhcp++_unittest.cc | 2 +-
src/lib/dhcp/tests/pkt4_unittest.cc | 27 ++++++++++
src/lib/dhcp/tests/pkt6_unittest.cc | 27 ++++++++++
14 files changed, 325 insertions(+), 5 deletions(-)
-----------------------------------------------------------------------
diff --git a/src/bin/dhcp4/dhcp4_messages.mes b/src/bin/dhcp4/dhcp4_messages.mes
index fca75bf..2e7b9b7 100644
--- a/src/bin/dhcp4/dhcp4_messages.mes
+++ b/src/bin/dhcp4/dhcp4_messages.mes
@@ -27,6 +27,14 @@ successfully established a session with the BIND 10 control channel.
This debug message is issued just before the IPv4 DHCP server attempts
to establish a session with the BIND 10 control channel.
+% DHCP4_CLASS_PROCESSING_FAILED client class specific processing failed
+This debug message means that the server processing that is unique for each
+client class has reported a failure. The response packet will not be sent.
+
+% DHCP4_CLASS_ASSIGNED client packet has been assigned to the following class(es): %1
+This debug message informs that incoming packet has been assigned to specified
+class or classes. This is a norma
+
% DHCP4_COMMAND_RECEIVED received command %1, arguments: %2
A debug message listing the command (and possible arguments) received
from the BIND 10 control system by the IPv4 DHCP server.
diff --git a/src/bin/dhcp4/dhcp4_srv.cc b/src/bin/dhcp4/dhcp4_srv.cc
index 169326a..1d58870 100644
--- a/src/bin/dhcp4/dhcp4_srv.cc
+++ b/src/bin/dhcp4/dhcp4_srv.cc
@@ -21,6 +21,7 @@
#include <dhcp/option_int.h>
#include <dhcp/option_int_array.h>
#include <dhcp/option_vendor.h>
+#include <dhcp/option_string.h>
#include <dhcp/pkt4.h>
#include <dhcp/docsis3_option_defs.h>
#include <dhcp4/dhcp4_log.h>
@@ -296,6 +297,9 @@ Dhcpv4Srv::run() {
callout_handle->getArgument("query4", query);
}
+ // Assign this packet to one or more classes if needed
+ classifyPacket(query);
+
try {
switch (query->getType()) {
case DHCPDISCOVER:
@@ -354,8 +358,18 @@ Dhcpv4Srv::run() {
adjustRemoteAddr(query, rsp);
+ if (!classSpecificProcessing(query, rsp)) {
+ /// @todo add more verbosity here
+ LOG_DEBUG(dhcp4_logger, DBG_DHCP4_BASIC, DHCP4_CLASS_PROCESSING_FAILED);
+
+ continue;
+ }
+
// If not client's query wasn't relayed, send response to the
// DHCP client's port. Otherwise, to server/relay port.
+
+ // Alternate version:
+ // if (query->getRemotePort() == DHCP4_CLIENT_PORT) {
if (!query->getHops()) {
rsp->setRemotePort(DHCP4_CLIENT_PORT);
} else {
@@ -1360,6 +1374,69 @@ Dhcpv4Srv::unpackOptions(const OptionBuffer& buf,
return (offset);
}
+void Dhcpv4Srv::classifyPacket(const Pkt4Ptr& pkt) {
+ boost::shared_ptr<OptionString> vendor_class =
+ boost::dynamic_pointer_cast<OptionString>(pkt->getOption(DHO_VENDOR_CLASS_IDENTIFIER));
+
+ string classes = "";
+
+ if (!vendor_class) {
+ return;
+ }
+
+ // DOCSIS specific section
+ if (vendor_class->getValue().find("docsis3.0") != std::string::npos) {
+ pkt->addClass("docsis3.0");
+ classes += "docsis3.0 ";
+ }
+
+ if (vendor_class->getValue().find("eRouter1.0") != std::string::npos) {
+ pkt->addClass("eRouter1.0");
+ classes += "eRouter1.0 ";
+ }
+
+ classes += vendor_class->getValue();
+ pkt->addClass(vendor_class->getValue());
+
+ if (!classes.empty()) {
+ LOG_DEBUG(dhcp4_logger, DBG_DHCP4_BASIC, DHCP4_CLASS_ASSIGNED)
+ .arg(classes);
+ }
+}
+
+bool Dhcpv4Srv::classSpecificProcessing(const Pkt4Ptr& query, const Pkt4Ptr& rsp) {
+
+ Subnet4Ptr subnet = selectSubnet(query);
+ if (!subnet) {
+ return (true);
+ }
+
+ if (query->inClass("docsis3.0")) {
+
+ // set next-server
+ rsp->setSiaddr(subnet->getSiaddr());
+
+ Subnet::OptionDescriptor desc =
+ subnet->getOptionDescriptor("dhcp4", DHO_BOOT_FILE_NAME);
+
+ if (desc.option) {
+ boost::shared_ptr<OptionString> boot =
+ boost::dynamic_pointer_cast<OptionString>(desc.option);
+ if (boot) {
+ std::string filename = boot->getValue();
+ rsp->setFile((const uint8_t*)filename.c_str(), filename.size());
+ }
+ }
+ }
+
+ if (query->inClass("eRouter1.0")) {
+
+
+ }
+
+ return (true);
+}
+
} // namespace dhcp
} // namespace isc
diff --git a/src/bin/dhcp4/dhcp4_srv.h b/src/bin/dhcp4/dhcp4_srv.h
index 66fe3a6..8e9f58b 100644
--- a/src/bin/dhcp4/dhcp4_srv.h
+++ b/src/bin/dhcp4/dhcp4_srv.h
@@ -373,6 +373,19 @@ protected:
const std::string& option_space,
isc::dhcp::OptionCollection& options);
+ /// @brief Assigns incoming packet to a given class
+ /// @param pkt packet to be classified
+ void classifyPacket(const Pkt4Ptr& pkt);
+
+ /// @brief Performs packet processing specific to a class
+ ///
+ /// This processing is a likely candidate to be pushed into hooks.
+ ///
+ /// @param query incoming client's packet
+ /// @param rsp server's response
+ /// @return true if successful, false otherwise (will prevent sending response)
+ bool classSpecificProcessing(const Pkt4Ptr& query, const Pkt4Ptr& rsp);
+
private:
/// @brief Constructs netmask option based on subnet4
diff --git a/src/bin/dhcp4/tests/dhcp4_srv_unittest.cc b/src/bin/dhcp4/tests/dhcp4_srv_unittest.cc
index e243c3b..1d1d9d9 100644
--- a/src/bin/dhcp4/tests/dhcp4_srv_unittest.cc
+++ b/src/bin/dhcp4/tests/dhcp4_srv_unittest.cc
@@ -153,6 +153,7 @@ public:
using Dhcpv4Srv::sanityCheck;
using Dhcpv4Srv::srvidToString;
using Dhcpv4Srv::unpackOptions;
+ using Dhcpv4Srv::classifyPacket;
};
#endif
@@ -2758,6 +2759,34 @@ TEST_F(HooksDhcpv4SrvTest, lease4ReleaseSkip) {
//EXPECT_EQ(leases.size(), 1);
}
+// Checks if client packets are classified properly
+TEST_F(Dhcpv4SrvTest, clientClassification) {
+
+ NakedDhcpv4Srv srv(0);
+
+ // Let's create a relayed DISCOVER. This particular relayed DISCOVER has
+ // vendor-class set to docsis3.0
+ Pkt4Ptr dis1;
+ ASSERT_NO_THROW(dis1 = captureRelayedDiscover());
+ ASSERT_NO_THROW(dis1->unpack());
+
+ srv.classifyPacket(dis1);
+
+ EXPECT_TRUE(dis1->inClass("docsis3.0"));
+ EXPECT_FALSE(dis1->inClass("eRouter1.0"));
+
+ // Let's create a relayed DISCOVER. This particular relayed DISCOVER has
+ // vendor-class set to eRouter1.0
+ Pkt4Ptr dis2;
+ ASSERT_NO_THROW(dis2 = captureRelayedDiscover2());
+ ASSERT_NO_THROW(dis2->unpack());
+
+ srv.classifyPacket(dis2);
+
+ EXPECT_TRUE(dis2->inClass("eRouter1.0"));
+ EXPECT_FALSE(dis2->inClass("docsis3.0"));
+}
+
}; // end of isc::dhcp::test namespace
}; // end of isc::dhcp namespace
}; // end of isc namespace
diff --git a/src/bin/dhcp4/tests/dhcp4_test_utils.h b/src/bin/dhcp4/tests/dhcp4_test_utils.h
index 2e39a8b..90abda1 100644
--- a/src/bin/dhcp4/tests/dhcp4_test_utils.h
+++ b/src/bin/dhcp4/tests/dhcp4_test_utils.h
@@ -178,11 +178,20 @@ public:
/// @brief returns captured DISCOVER that went through a relay
///
- /// See method code for a detailed explanation.
+ /// See method code for a detailed explanation. This is a discover from
+ /// docsis3.0 device (Cable Modem)
///
/// @return relayed DISCOVER
Pkt4Ptr captureRelayedDiscover();
+ /// @brief returns captured DISCOVER that went through a relay
+ ///
+ /// See method code for a detailed explanation. This is a discover from
+ /// eRouter1.0 device (CPE device integrated with cable modem)
+ ///
+ /// @return relayed DISCOVER
+ Pkt4Ptr captureRelayedDiscover2();
+
/// @brief generates a DHCPv4 packet based on provided hex string
///
/// @return created packet
@@ -308,6 +317,7 @@ public:
using Dhcpv4Srv::sanityCheck;
using Dhcpv4Srv::srvidToString;
using Dhcpv4Srv::unpackOptions;
+ using Dhcpv4Srv::classifyPacket;
};
}; // end of isc::dhcp::test namespace
diff --git a/src/bin/dhcp4/tests/wireshark.cc b/src/bin/dhcp4/tests/wireshark.cc
index 80b4737..c07bc1b 100644
--- a/src/bin/dhcp4/tests/wireshark.cc
+++ b/src/bin/dhcp4/tests/wireshark.cc
@@ -71,7 +71,10 @@ void Dhcpv4SrvTest::captureSetDefaultFields(const Pkt4Ptr& pkt) {
Pkt4Ptr Dhcpv4SrvTest::captureRelayedDiscover() {
-/* string exported from Wireshark:
+/* This is packet 1 from capture
+ dhcp-val/pcap/docsis-*-CG3000DCR-Registration-Filtered.cap
+
+string exported from Wireshark:
User Datagram Protocol, Src Port: bootps (67), Dst Port: bootps (67)
Source port: bootps (67)
@@ -98,7 +101,7 @@ Bootstrap Protocol
Magic cookie: DHCP
Option: (53) DHCP Message Type
Option: (55) Parameter Request List
- Option: (60) Vendor class identifier
+ Option: (60) Vendor class identifier (docsis3.0)
Option: (125) V-I Vendor-specific Information
- suboption 1 (Option Request): requesting option 2
- suboption 5 (Modem Caps): 117 bytes
@@ -129,6 +132,59 @@ Bootstrap Protocol
return (packetFromCapture(hex_string));
}
+Pkt4Ptr Dhcpv4SrvTest::captureRelayedDiscover2() {
+
+/* This is packet 5 from capture
+ dhcp-val/pcap/docsis-*-CG3000DCR-Registration-Filtered.cap
+
+string exported from Wireshark:
+
+User Datagram Protocol, Src Port: bootps (67), Dst Port: bootps (67)
+Bootstrap Protocol
+ Message type: Boot Request (1)
+ Hardware type: Ethernet (0x01)
+ Hardware address length: 6
+ Hops: 1
+ Transaction ID: 0x5d05478f
+ Seconds elapsed: 5
+ Bootp flags: 0x0000 (Unicast)
+ Client IP address: 0.0.0.0 (0.0.0.0)
+ Your (client) IP address: 0.0.0.0 (0.0.0.0)
+ Next server IP address: 0.0.0.0 (0.0.0.0)
+ Relay agent IP address: 10.254.226.1 (10.254.226.1)
+ Client MAC address: Netgear_b8:15:15 (20:e5:2a:b8:15:15)
+ Client hardware address padding: 00000000000000000000
+ Server host name not given
+ Boot file name not given
+ Magic cookie: DHCP
+ Option: (53) DHCP Message Type
+ Option: (55) Parameter Request List
+ Option: (43) Vendor-Specific Information
+ Option: (60) Vendor class identifier (eRouter1.0)
+ Option: (15) Domain Name
+ Option: (61) Client identifier
+ Option: (57) Maximum DHCP Message Size
+ Option: (82) Agent Information Option
+ Option: (255) End */
+
+ string hex_string =
+ "010106015d05478f000500000000000000000000000000000afee20120e52ab8151500"
+ "0000000000000000000000000000000000000000000000000000000000000000000000"
+ "0000000000000000000000000000000000000000000000000000000000000000000000"
+ "0000000000000000000000000000000000000000000000000000000000000000000000"
+ "0000000000000000000000000000000000000000000000000000000000000000000000"
+ "0000000000000000000000000000000000000000000000000000000000000000000000"
+ "000000000000000000000000000000000000000000000000000063825363350101370e"
+ "480102030406070c0f171a36337a2b63020745524f55544552030b45434d3a45524f55"
+ "544552040d324252323239553430303434430504312e3034060856312e33332e303307"
+ "07322e332e305232080630303039354209094347333030304443520a074e6574676561"
+ "720f0745524f555445523c0a65526f75746572312e300f14687364312e70612e636f6d"
+ "636173742e6e65742e3d0fff2ab815150003000120e52ab81515390205dc5219010420"
+ "000002020620e52ab8151409090000118b0401020300ff";
+
+ return (packetFromCapture(hex_string));
+}
+
}; // end of isc::dhcp::test namespace
}; // end of isc::dhcp namespace
}; // end of isc namespace
diff --git a/src/lib/dhcp/pkt4.cc b/src/lib/dhcp/pkt4.cc
index 40df6d0..a8dc544 100644
--- a/src/lib/dhcp/pkt4.cc
+++ b/src/lib/dhcp/pkt4.cc
@@ -459,6 +459,18 @@ Pkt4::updateTimestamp() {
timestamp_ = boost::posix_time::microsec_clock::universal_time();
}
+bool
+Pkt4::inClass(const std::string& client_class) {
+ return (classes_.find(client_class) != classes_.end());
+}
+
+void
+Pkt4::addClass(const std::string& client_class) {
+ if (classes_.find(client_class) == classes_.end()) {
+ classes_.insert(client_class);
+ }
+}
+
} // end of namespace isc::dhcp
} // end of namespace isc
diff --git a/src/lib/dhcp/pkt4.h b/src/lib/dhcp/pkt4.h
index be82e13..d613e0b 100644
--- a/src/lib/dhcp/pkt4.h
+++ b/src/lib/dhcp/pkt4.h
@@ -26,6 +26,7 @@
#include <iostream>
#include <vector>
+#include <set>
#include <time.h>
@@ -52,6 +53,9 @@ public:
/// to check whether client requested broadcast response.
const static uint16_t FLAG_BROADCAST_MASK = 0x8000;
+ /// Container for storing client classes
+ typedef std::set<std::string> Classes;
+
/// Constructor, used in replying to a message.
///
/// @param msg_type type of message (e.g. DHCPDISOVER=1)
@@ -531,6 +535,27 @@ public:
/// performance).
std::vector<uint8_t> data_;
+ /// @brief Checks whether a client belongs to a given class
+ ///
+ /// @param client_class name of the class
+ /// @return true if belongs
+ bool inClass(const std::string& client_class);
+
+ /// @brief Adds packet to a specified class
+ ///
+ /// A packet can be added to the same class repeatedly. Any additional
+ /// attempts to add to a class the packet already belongs to, will be
+ /// ignored silently.
+ ///
+ /// @param client_class name of the class to be added
+ void addClass(const std::string& client_class);
+
+ /// @brief Classes this packet belongs to.
+ ///
+ /// This field is public, so code can iterate over existing classes.
+ /// Having it public also solves the problem of returned reference lifetime.
+ Classes classes_;
+
private:
/// @brief Generic method that validates and sets HW address.
diff --git a/src/lib/dhcp/pkt6.cc b/src/lib/dhcp/pkt6.cc
index 10cc173..89caade 100644
--- a/src/lib/dhcp/pkt6.cc
+++ b/src/lib/dhcp/pkt6.cc
@@ -584,6 +584,17 @@ void Pkt6::copyRelayInfo(const Pkt6Ptr& question) {
}
}
+bool
+Pkt6::inClass(const std::string& client_class) {
+ return (classes_.find(client_class) != classes_.end());
+}
+
+void
+Pkt6::addClass(const std::string& client_class) {
+ if (classes_.find(client_class) == classes_.end()) {
+ classes_.insert(client_class);
+ }
+}
} // end of isc::dhcp namespace
} // end of isc namespace
diff --git a/src/lib/dhcp/pkt6.h b/src/lib/dhcp/pkt6.h
index 207f576..10d1d82 100644
--- a/src/lib/dhcp/pkt6.h
+++ b/src/lib/dhcp/pkt6.h
@@ -23,6 +23,7 @@
#include <boost/shared_ptr.hpp>
#include <iostream>
+#include <set>
#include <time.h>
@@ -47,6 +48,9 @@ public:
TCP = 1 // there are TCP DHCPv6 packets (bulk leasequery, failover)
};
+ /// Container for storing client classes
+ typedef std::set<std::string> Classes;
+
/// @brief defines relay search pattern
///
/// Defines order in which options are searched in a message that
@@ -425,6 +429,27 @@ public:
/// data format change etc.
OptionBuffer data_;
+ /// @brief Checks whether a client belongs to a given class
+ ///
+ /// @param client_class name of the class
+ /// @return true if belongs
+ bool inClass(const std::string& client_class);
+
+ /// @brief Adds packet to a specified class
+ ///
+ /// A packet can be added to the same class repeatedly. Any additional
+ /// attempts to add to a class the packet already belongs to, will be
+ /// ignored silently.
+ ///
+ /// @param client_class name of the class to be added
+ void addClass(const std::string& client_class);
+
+ /// @brief Classes this packet belongs to.
+ ///
+ /// This field is public, so code can iterate over existing classes.
+ /// Having it public also solves the problem of returned reference lifetime.
+ Classes classes_;
+
protected:
/// Builds on wire packet for TCP transmission.
///
diff --git a/src/lib/dhcp/std_option_defs.h b/src/lib/dhcp/std_option_defs.h
index 3e0ec1f..e7e5faf 100644
--- a/src/lib/dhcp/std_option_defs.h
+++ b/src/lib/dhcp/std_option_defs.h
@@ -160,7 +160,7 @@ const OptionDefParams OPTION_DEF_PARAMS4[] = {
{ "dhcp-rebinding-time", DHO_DHCP_REBINDING_TIME,
OPT_UINT32_TYPE, false, NO_RECORD_DEF, "" },
{ "vendor-class-identifier", DHO_VENDOR_CLASS_IDENTIFIER,
- OPT_BINARY_TYPE, false, NO_RECORD_DEF, "" },
+ OPT_STRING_TYPE, false, NO_RECORD_DEF, "" },
{ "dhcp-client-identifier", DHO_DHCP_CLIENT_IDENTIFIER,
OPT_BINARY_TYPE, false, NO_RECORD_DEF, "" },
{ "nwip-domain-name", DHO_NWIP_DOMAIN_NAME, OPT_STRING_TYPE, false, NO_RECORD_DEF, "" },
diff --git a/src/lib/dhcp/tests/libdhcp++_unittest.cc b/src/lib/dhcp/tests/libdhcp++_unittest.cc
index 016ddf6..7f915de 100644
--- a/src/lib/dhcp/tests/libdhcp++_unittest.cc
+++ b/src/lib/dhcp/tests/libdhcp++_unittest.cc
@@ -758,7 +758,7 @@ TEST_F(LibDhcpTest, stdOptionDefs4) {
typeid(OptionInt<uint32_t>));
LibDhcpTest::testStdOptionDefs4(DHO_VENDOR_CLASS_IDENTIFIER, begin, end,
- typeid(Option));
+ typeid(OptionString));
LibDhcpTest::testStdOptionDefs4(DHO_DHCP_CLIENT_IDENTIFIER, begin, end,
typeid(Option));
diff --git a/src/lib/dhcp/tests/pkt4_unittest.cc b/src/lib/dhcp/tests/pkt4_unittest.cc
index 72ffff7..365b10f 100644
--- a/src/lib/dhcp/tests/pkt4_unittest.cc
+++ b/src/lib/dhcp/tests/pkt4_unittest.cc
@@ -798,4 +798,31 @@ TEST_F(Pkt4Test, hwaddrSrcRemote) {
remote_addr->hwaddr_.begin()));
}
+// Tests whether a packet can be assigned to a class and later
+// checked if it belongs to a given class
+TEST_F(Pkt4Test, clientClasses) {
+ Pkt4 pkt(DHCPOFFER, 1234);
+
+ // Default values (do not belong to any class)
+ EXPECT_FALSE(pkt.inClass("eRouter1.0"));
+ EXPECT_FALSE(pkt.inClass("docsis3.0"));
+ EXPECT_TRUE(pkt.classes_.empty());
+
+ // Add to the first class
+ pkt.addClass("eRouter1.0");
+ EXPECT_TRUE(pkt.inClass("eRouter1.0"));
+ EXPECT_FALSE(pkt.inClass("docsis3.0"));
+ ASSERT_FALSE(pkt.classes_.empty());
+
+ // Add to a second class
+ pkt.addClass("docsis3.0");
+ EXPECT_TRUE(pkt.inClass("eRouter1.0"));
+ EXPECT_TRUE(pkt.inClass("docsis3.0"));
+
+ // Check that it's ok to add to the same class repeatedly
+ EXPECT_NO_THROW(pkt.addClass("foo"));
+ EXPECT_NO_THROW(pkt.addClass("foo"));
+ EXPECT_NO_THROW(pkt.addClass("foo"));
+}
+
} // end of anonymous namespace
diff --git a/src/lib/dhcp/tests/pkt6_unittest.cc b/src/lib/dhcp/tests/pkt6_unittest.cc
index e18b545..a0139df 100644
--- a/src/lib/dhcp/tests/pkt6_unittest.cc
+++ b/src/lib/dhcp/tests/pkt6_unittest.cc
@@ -779,4 +779,31 @@ TEST_F(Pkt6Test, getAnyRelayOption) {
EXPECT_FALSE(opt);
}
+// Tests whether a packet can be assigned to a class and later
+// checked if it belongs to a given class
+TEST_F(Pkt6Test, clientClasses) {
+ Pkt6 pkt(DHCPV6_ADVERTISE, 1234);
+
+ // Default values (do not belong to any class)
+ EXPECT_FALSE(pkt.inClass("eRouter1.0"));
+ EXPECT_FALSE(pkt.inClass("docsis3.0"));
+ EXPECT_TRUE(pkt.classes_.empty());
+
+ // Add to the first class
+ pkt.addClass("eRouter1.0");
+ EXPECT_TRUE(pkt.inClass("eRouter1.0"));
+ EXPECT_FALSE(pkt.inClass("docsis3.0"));
+ ASSERT_FALSE(pkt.classes_.empty());
+
+ // Add to a second class
+ pkt.addClass("docsis3.0");
+ EXPECT_TRUE(pkt.inClass("eRouter1.0"));
+ EXPECT_TRUE(pkt.inClass("docsis3.0"));
+
+ // Check that it's ok to add to the same class repeatedly
+ EXPECT_NO_THROW(pkt.addClass("foo"));
+ EXPECT_NO_THROW(pkt.addClass("foo"));
+ EXPECT_NO_THROW(pkt.addClass("foo"));
+}
+
}
More information about the bind10-changes
mailing list