From: Tomek Mrugalski Date: Mon, 24 Feb 2014 18:20:15 +0000 (+0100) Subject: [master] Merge branch 'trac3322' (relay override in client classification) X-Git-Tag: bind10-1.2.0beta1-release~27 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=dbedf1862bc30ffd3e21140f2a6e72302d769b7a;p=thirdparty%2Fkea.git [master] Merge branch 'trac3322' (relay override in client classification) Conflicts: ChangeLog src/bin/dhcp6/tests/dhcp6_srv_unittest.cc --- dbedf1862bc30ffd3e21140f2a6e72302d769b7a diff --cc ChangeLog index f4e58ab4d5,f362789d2e..c763736e68 --- a/ChangeLog +++ b/ChangeLog @@@ -1,50 -1,9 +1,57 @@@ -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 diff --cc src/bin/dhcp6/tests/dhcp6_srv_unittest.cc index 2900118278,9f1b431f23..753bafc4f6 --- a/src/bin/dhcp6/tests/dhcp6_srv_unittest.cc +++ b/src/bin/dhcp6/tests/dhcp6_srv_unittest.cc @@@ -1803,33 -1798,149 +1798,174 @@@ TEST_F(Dhcpv6SrvTest, clientClassify2) 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