-7XX. [func] tomek
++759. [func] tomek
+ b10-dhcp4, b10-dhcp6: IP address of the relay agent can now be specified
+ for both IPv4 and IPv6 subnets. That information allows the server to
+ properly handle a case where relay agent address does not match subnet.
+ This is mostly useful in shared subnets and cable networks.
- (Trac #3322, git abcd)
++ (Trac #3322, git 5de565baea42c9096dff78ed5fbd05982a174469)
++
+758. [bug] tmark
+ b10-dhcp4 now correctly handles DHO_HOST_OPTION. This corrects a bug
+ where the server would fail to recognize the option in the DHCP request
+ and then skip generating the appropriate DHCP-DDNS update request.
+ (Trac #2426, git 985d66cba7665a71e17ef70c5d22c767abaad1b6)
+
+757. [func] tmark
+ b10-dhcp6 now parses parameters which support DHCP-DDNS updates via
+ the DHCP-DDNS module, b10-dhcp-ddns. These parameters are part of new
+ configuration element, dhcp-ddns, defined in dhcp4.spec. These parameters
+ influence when and how DDNS updates requests are created but communicating
+ them to b10-dhcp-ddns is not yet supported. That will be provided under
+ separate ticket, Trac #3222.
+ (Trac# 3034, git 22c667a66536ff3e3741bc67025d824644ed4e7d)
+
+756. [bug] marcin
+ b10-dhcp6: server parses DHCPv6 Vendor Class option. Previously
+ the server failed to parse Vendor Class option having empty opaque
+ data field because of the invalid definition in libdhcp++. The
+ DHCPv6 Vendor Class option and DHCPv4 V-I Vendor Class option is
+ now represented by the new OptionVendorClass. The b10-dhcp4 is
+ affected by this change such that it uses new class to parse the
+ DHCPv4 V-I Vendor Class option.
+ (Trac #3316, git 1e61d7db5b8dc76682aa568cd62bfae0eeff46e3)
+
+755. [func] muks
+ Add support for the CAA RR type (RFC 6844).
+ (Trac #2512, git 39162608985e5c904448f308951c73bb9c32da8f)
+
+754. [func] muks
+ Add support for the TLSA RR type (RFC 6698).
+ (Trac #2185, git a168170430f6927f28597b2a6debebe31cf39b13)
+
+753. [func] muks
+ libdns++: the unknown/generic (RFC 3597) RDATA class now uses the
+ generic lexer in constructors from text.
+ (Trac #2426, git 0770d2df84e5608371db3a47e0456eb2a340b5f4)
+
+752. [func] tmark
+ If configured to do so, b10-dhcp4 will now create DHCP-DDNS update
+ requests and send them to b10-dhcp-ddns for processing.
+ (Trac# 3329, git 4546dd186782eec5cfcb4ddb61b0a3aa5c700751)
+
+751. [func] muks
+ The BIND 10 zone loader now supports the $GENERATE directive (a
+ BIND 9 extension).
+ (Trac #2430, git b05064f681231fe7f8571253c5786f4ff0f2ca03)
750. [func] tomek
b10-dhcp4, b10-dhcp6: Simple client classification has been
sol->addClass("foo");
// This time it should work
- EXPECT_TRUE(srv.selectSubnet(sol));
+ 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());
++}
++
+ // Checks if relay IP address specified in the relay-info structure in
+ // subnet6 is being used properly.
+ TEST_F(Dhcpv6SrvTest, relayOverride) {
+ // We have 2 subnets defined. Note that both have a relay address
+ // defined. Both are not belonging to the subnets. That is
+ // important, because if the relay belongs to the subnet, there's
+ // no need to specify relay override.
+ string config = "{ \"interfaces\": [ \"*\" ],"
+ "\"preferred-lifetime\": 3000,"
+ "\"rebind-timer\": 2000, "
+ "\"renew-timer\": 1000, "
+ "\"subnet6\": [ "
+ " { \"pool\": [ \"2001:db8:1::/64\" ],"
+ " \"subnet\": \"2001:db8:1::/48\", "
+ " \"relay\": { "
+ " \"ip-address\": \"2001:db8:3::1\""
+ " }"
+ " }, "
+ " { \"pool\": [ \"2001:db8:2::/64\" ],"
+ " \"subnet\": \"2001:db8:2::/48\", "
+ " \"relay\": { "
+ " \"ip-address\": \"2001:db8:3::2\""
+ " }"
+ " } "
+ "],"
+ "\"valid-lifetime\": 4000 }";
+
+ // Use this config to set up the server
+ ASSERT_NO_THROW(configure(config));
+
+ // Let's get the subnet configuration objects
+ const Subnet6Collection* subnets = CfgMgr::instance().getSubnets6();
+ ASSERT_EQ(2, subnets->size());
+
+ // Let's get them for easy reference
+ Subnet6Ptr subnet1 = (*subnets)[0];
+ Subnet6Ptr subnet2 = (*subnets)[1];
+ ASSERT_TRUE(subnet1);
+ ASSERT_TRUE(subnet2);
+
+ 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);
+
+ // Now pretend the packet came via one relay.
+ Pkt6::RelayInfo relay;
+ relay.linkaddr_ = IOAddress("2001:db8:1::1");
+ relay.peeraddr_ = IOAddress("fe80::1");
+
+ sol->relay_info_.push_back(relay);
+
+ // This is just a sanity check, we're using regular method: the relay
+ // belongs to the first (2001:db8:1::/64) subnet, so it's an easy decision.
+ EXPECT_TRUE(subnet1 == srv_.selectSubnet(sol));
+
+ // Relay belongs to the second subnet, so it should be selected.
+ sol->relay_info_.back().linkaddr_ = IOAddress("2001:db8:2::1");
+ EXPECT_TRUE(subnet2 == srv_.selectSubnet(sol));
+
+ // Now let's check if the relay override for the first subnets works
+ sol->relay_info_.back().linkaddr_ = IOAddress("2001:db8:3::1");
+ EXPECT_TRUE(subnet1 == srv_.selectSubnet(sol));
+
+ // Now repeat that for relay matching the second subnet.
+ sol->relay_info_.back().linkaddr_ = IOAddress("2001:db8:3::2");
+ EXPECT_TRUE(subnet2 == srv_.selectSubnet(sol));
+
+ // Finally, let's check that completely mismatched relay will not get us
+ // anything
+ sol->relay_info_.back().linkaddr_ = IOAddress("2001:db8:1234::1");
+ EXPECT_FALSE(srv_.selectSubnet(sol));
+ }
+
+ // Checks if relay IP address specified in the relay-info structure can be
+ // used together with client-classification.
+ TEST_F(Dhcpv6SrvTest, relayOverrideAndClientClass) {
+
+ // This test configures 2 subnets. They both are on the same link, so they
+ // have the same relay-ip address. Furthermore, the first subnet is
+ // reserved for clients that belong to class "foo".
+ 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\", "
+ " \"relay\": { "
+ " \"ip-address\": \"2001:db8:3::1\""
+ " }"
+ " }, "
+ " { \"pool\": [ \"2001:db8:2::/64\" ],"
+ " \"subnet\": \"2001:db8:2::/48\", "
+ " \"relay\": { "
+ " \"ip-address\": \"2001:db8:3::1\""
+ " }"
+ " } "
+ "],"
+ "\"valid-lifetime\": 4000 }";
+
+ // Use this config to set up the server
+ ASSERT_NO_THROW(configure(config));
+
+ // Let's get the subnet configuration objects
+ const Subnet6Collection* subnets = CfgMgr::instance().getSubnets6();
+ ASSERT_EQ(2, subnets->size());
+
+ // Let's get them for easy reference
+ Subnet6Ptr subnet1 = (*subnets)[0];
+ Subnet6Ptr subnet2 = (*subnets)[1];
+ ASSERT_TRUE(subnet1);
+ ASSERT_TRUE(subnet2);
+
+ 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);
+
+ // Now pretend the packet came via one relay.
+ Pkt6::RelayInfo relay;
+ relay.linkaddr_ = IOAddress("2001:db8:3::1");
+ relay.peeraddr_ = IOAddress("fe80::1");
+
+ sol->relay_info_.push_back(relay);
+
+ // This packet does not belong to class foo, so it should be rejected in
+ // subnet[0], even though the relay-ip matches. It should be accepted in
+ // subnet[1], because the subnet matches and there are no class
+ // requirements.
+ EXPECT_TRUE(subnet2 == srv_.selectSubnet(sol));
+
+ // Now let's add this packet to class foo and recheck. This time it should
+ // be accepted in the first subnet, because both class and relay-ip match.
+ sol->addClass("foo");
+ EXPECT_TRUE(subnet1 == srv_.selectSubnet(sol));
}
/// @todo: Add more negative tests for processX(), e.g. extend sanityCheck() test