mirror of
https://gitlab.isc.org/isc-projects/kea
synced 2025-08-31 05:55:28 +00:00
[master] Merged trac4059 (layer 2 DHCPv6 relays)
This commit is contained in:
@@ -1043,7 +1043,13 @@ Dhcpv6Srv::selectSubnet(const Pkt6Ptr& question) {
|
||||
|
||||
// Initialize fields specific to relayed messages.
|
||||
if (!question->relay_info_.empty()) {
|
||||
selector.first_relay_linkaddr_ = question->relay_info_.back().linkaddr_;
|
||||
BOOST_REVERSE_FOREACH(Pkt6::RelayInfo relay, question->relay_info_) {
|
||||
if (!relay.linkaddr_.isV6Zero() &&
|
||||
!relay.linkaddr_.isV6LinkLocal()) {
|
||||
selector.first_relay_linkaddr_ = relay.linkaddr_;
|
||||
break;
|
||||
}
|
||||
}
|
||||
selector.interface_id_ =
|
||||
question->getAnyRelayOption(D6O_INTERFACE_ID,
|
||||
Pkt6::RELAY_GET_FIRST);
|
||||
|
@@ -1297,23 +1297,15 @@ TEST_F(Dhcpv6SrvTest, selectSubnetRelayLinkaddr) {
|
||||
Subnet6Ptr selected = srv.selectSubnet(pkt);
|
||||
EXPECT_FALSE(selected);
|
||||
|
||||
// CASE 2: We have three subnets defined and we received relayed traffic.
|
||||
// Nothing should be selected.
|
||||
CfgMgr::instance().clear();
|
||||
CfgMgr::instance().getStagingCfg()->getCfgSubnets6()->add(subnet1);
|
||||
CfgMgr::instance().getStagingCfg()->getCfgSubnets6()->add(subnet2);
|
||||
CfgMgr::instance().getStagingCfg()->getCfgSubnets6()->add(subnet3);
|
||||
CfgMgr::instance().commit();
|
||||
selected = srv.selectSubnet(pkt);
|
||||
EXPECT_EQ(selected, subnet2);
|
||||
|
||||
// CASE 3: We have three subnets defined and we received relayed traffic
|
||||
// CASE 2: We have three subnets defined and we received relayed traffic
|
||||
// that came out of subnet 2. We should select subnet2 then
|
||||
CfgMgr::instance().clear();
|
||||
CfgMgr::instance().getStagingCfg()->getCfgSubnets6()->add(subnet1);
|
||||
CfgMgr::instance().getStagingCfg()->getCfgSubnets6()->add(subnet2);
|
||||
CfgMgr::instance().getStagingCfg()->getCfgSubnets6()->add(subnet3);
|
||||
CfgMgr::instance().commit();
|
||||
selected = srv.selectSubnet(pkt);
|
||||
EXPECT_EQ(selected, subnet2);
|
||||
|
||||
// Source of the packet should have no meaning. Selection is based
|
||||
// on linkaddr field in the relay
|
||||
@@ -1321,6 +1313,64 @@ TEST_F(Dhcpv6SrvTest, selectSubnetRelayLinkaddr) {
|
||||
selected = srv.selectSubnet(pkt);
|
||||
EXPECT_EQ(selected, subnet2);
|
||||
|
||||
// But not when this linkaddr field is not usable.
|
||||
Pkt6::RelayInfo relay2;
|
||||
relay2.peeraddr_ = IOAddress("fe80::1");
|
||||
pkt->relay_info_.clear();
|
||||
pkt->relay_info_.push_back(relay2);
|
||||
selected = srv.selectSubnet(pkt);
|
||||
EXPECT_EQ(selected, subnet1);
|
||||
|
||||
// CASE 3: We have three subnets defined and we received relayed traffic
|
||||
// that came out a layer 2 relay on subnet 2. We should select subnet2 then
|
||||
CfgMgr::instance().clear();
|
||||
CfgMgr::instance().getStagingCfg()->getCfgSubnets6()->add(subnet1);
|
||||
CfgMgr::instance().getStagingCfg()->getCfgSubnets6()->add(subnet2);
|
||||
CfgMgr::instance().getStagingCfg()->getCfgSubnets6()->add(subnet3);
|
||||
CfgMgr::instance().commit();
|
||||
pkt->relay_info_.clear();
|
||||
pkt->relay_info_.push_back(relay);
|
||||
relay2.hop_count_ = 1;
|
||||
pkt->relay_info_.push_back(relay2);
|
||||
selected = srv.selectSubnet(pkt);
|
||||
EXPECT_EQ(selected, subnet2);
|
||||
|
||||
// The number of level 2 relay doesn't matter
|
||||
pkt->relay_info_.clear();
|
||||
Pkt6::RelayInfo relay20;
|
||||
relay20.peeraddr_ = IOAddress("fe80::1");
|
||||
pkt->relay_info_.push_back(relay20);
|
||||
Pkt6::RelayInfo relay21;
|
||||
relay21.peeraddr_ = IOAddress("fe80::1");
|
||||
relay21.hop_count_ = 1;
|
||||
pkt->relay_info_.push_back(relay21);
|
||||
relay.hop_count_ = 2;
|
||||
pkt->relay_info_.push_back(relay);
|
||||
Pkt6::RelayInfo relay22;
|
||||
relay22.peeraddr_ = IOAddress("fe80::1");
|
||||
relay22.hop_count_ = 3;
|
||||
pkt->relay_info_.push_back(relay22);
|
||||
Pkt6::RelayInfo relay23;
|
||||
relay23.peeraddr_ = IOAddress("fe80::1");
|
||||
relay23.hop_count_ = 4;
|
||||
pkt->relay_info_.push_back(relay23);
|
||||
selected = srv.selectSubnet(pkt);
|
||||
EXPECT_EQ(selected, subnet2);
|
||||
|
||||
// Only the inner/last relay with a usable address matters
|
||||
pkt->relay_info_.clear();
|
||||
pkt->relay_info_.push_back(relay20);
|
||||
pkt->relay_info_.push_back(relay21);
|
||||
pkt->relay_info_.push_back(relay);
|
||||
pkt->relay_info_.push_back(relay22);
|
||||
Pkt6::RelayInfo relay3;
|
||||
relay3.linkaddr_ = IOAddress("2001:db8:3::1234");
|
||||
relay3.peeraddr_ = IOAddress("fe80::1");
|
||||
relay3.hop_count_ = 4;
|
||||
pkt->relay_info_.push_back(relay3);
|
||||
selected = srv.selectSubnet(pkt);
|
||||
EXPECT_EQ(selected, subnet3);
|
||||
|
||||
// CASE 4: We have three subnets defined and we received relayed traffic
|
||||
// that came out of undefined subnet. We should select nothing
|
||||
CfgMgr::instance().clear();
|
||||
@@ -1329,6 +1379,7 @@ TEST_F(Dhcpv6SrvTest, selectSubnetRelayLinkaddr) {
|
||||
CfgMgr::instance().getStagingCfg()->getCfgSubnets6()->add(subnet3);
|
||||
CfgMgr::instance().commit();
|
||||
pkt->relay_info_.clear();
|
||||
relay.hop_count_ = 0;
|
||||
relay.linkaddr_ = IOAddress("2001:db8:4::1234");
|
||||
pkt->relay_info_.push_back(relay);
|
||||
selected = srv.selectSubnet(pkt);
|
||||
|
Reference in New Issue
Block a user