// Initialize fields specific to relayed messages.
if (!query->relay_info_.empty()) {
for (auto const& relay : boost::adaptors::reverse(query->relay_info_)) {
+ // Note that a link local address is useless so skip it.
if (!relay.linkaddr_.isV6Zero() &&
!relay.linkaddr_.isV6LinkLocal()) {
selector.first_relay_linkaddr_ = relay.linkaddr_;
CfgSubnets6::selectSubnet(const SubnetSelector& selector) const {
ConstSubnet6Ptr subnet;
- // If relay agent link address is set to zero it means that we're dealing
- // with a directly connected client.
- if (selector.first_relay_linkaddr_ == IOAddress("::")) {
+ // If relay agent link address is set to zero and there is no interface id
+ // it means that we're dealing with a directly connected client.
+ if ((selector.first_relay_linkaddr_ == IOAddress("::")) &&
+ !selector.interface_id_) {
// If interface name is known try to match it with interface names
// specified for configured subnets.
if (!selector.iface_name_.empty()) {
// If Interface ID option could not be matched for any subnet, try
// the relay agent link address.
- if (!subnet) {
+ if (!subnet && (selector.first_relay_linkaddr_ != IOAddress("::"))) {
subnet = selectSubnet(selector.first_relay_linkaddr_,
selector.client_classes_,
true);
}
// This test checks that the subnet can be selected using an interface
-// name associated with a asubnet.
+// name associated with a subnet.
TEST(CfgSubnets6Test, selectSubnetByInterfaceName) {
CfgSubnets6 cfg;
}
// This test checks that the subnet can be selected using an Interface ID
-// option inserted by a relay.
+// option inserted by a relay (TODO: merge with the L2 variant).
TEST(CfgSubnets6Test, selectSubnetByInterfaceId) {
CfgSubnets6 cfg;
EXPECT_FALSE(cfg.selectSubnet(selector));
}
+// This test checks that the subnet can be selected using an Interface ID
+// option inserted by a L2 relay.
+TEST(CfgSubnets6Test, selectSubnetByInterfaceIdL2) {
+ CfgSubnets6 cfg;
+
+ // Create 3 subnets.
+ Subnet6Ptr subnet1(new Subnet6(IOAddress("2000::"),
+ 48, 1, 2, 3, 4, SubnetID(1)));
+ Subnet6Ptr subnet2(new Subnet6(IOAddress("3000::"),
+ 48, 1, 2, 3, 4, SubnetID(2)));
+ Subnet6Ptr subnet3(new Subnet6(IOAddress("4000::"),
+ 48, 1, 2, 3, 4, SubnetID(3)));
+
+ // Create Interface-id options used in subnets 1,2, and 3
+ OptionPtr ifaceid1 = generateInterfaceId("relay1.eth0");
+ OptionPtr ifaceid2 = generateInterfaceId("VL32");
+ // That's a strange interface-id, but this is a real life example
+ OptionPtr ifaceid3 = generateInterfaceId("ISAM144|299|ipv6|nt:vp:1:110");
+
+ // Bogus interface-id.
+ OptionPtr ifaceid_bogus = generateInterfaceId("non-existent");
+
+ // Assign interface ids to the respective subnets.
+ subnet1->setInterfaceId(ifaceid1);
+ subnet2->setInterfaceId(ifaceid2);
+ subnet3->setInterfaceId(ifaceid3);
+
+ // There shouldn't be any subnet configured at this stage.
+ SubnetSelector selector;
+ selector.interface_id_ = ifaceid1;
+ // No longer need to set the relay link address.
+ EXPECT_FALSE(cfg.selectSubnet(selector));
+
+ // Add one of the subnets.
+ cfg.add(subnet1);
+
+ // If only one subnet has been specified, it should be returned when the
+ // interface id matches. But, for a different interface id there should be
+ // no match.
+ EXPECT_EQ(subnet1, cfg.selectSubnet(selector));
+ selector.interface_id_ = ifaceid2;
+ EXPECT_FALSE(cfg.selectSubnet(selector));
+
+ // Add other subnets.
+ cfg.add(subnet2);
+ cfg.add(subnet3);
+
+ // Now that we have all subnets added. we should be able to retrieve them
+ // using appropriate interface ids.
+ selector.interface_id_ = ifaceid3;
+ EXPECT_EQ(subnet3, cfg.selectSubnet(selector));
+ selector.interface_id_ = ifaceid2;
+ EXPECT_EQ(subnet2, cfg.selectSubnet(selector));
+
+ // For invalid interface id, there should be nothing returned.
+ selector.interface_id_ = ifaceid_bogus;
+ EXPECT_FALSE(cfg.selectSubnet(selector));
+}
+
// Test that the client classes are considered when the subnet is selected by
// the relay link address.
TEST(CfgSubnets6Test, selectSubnetByRelayAddressAndClassify) {
// If we have only a single subnet and the request came from a local
// address, let's use that subnet
SubnetSelector selector;
- selector.first_relay_linkaddr_ = IOAddress("5000::1");
+ // No longer need to set the relay link address.
selector.client_classes_.insert("bar");
selector.interface_id_ = ifaceid1;
EXPECT_EQ(subnet1, cfg.selectSubnet(selector));