Files
openthread/tests/nexus/test_1_3_DBR_TC_8.cpp
Abtin Keshavarzian 064529cbfc [nexus] add helper to allow link between nodes in nexus (#12906)
Added `Core::AllowLinkBetween()` and `Core::UnallowLinkBetween()`
helper methods to the Nexus test platform. These methods simplify
establishing bidirectional links between nodes in simulation tests by
handling the reciprocal `AllowList()` calls in a single step.

Updated various Nexus test cases to utilize these new helpers,
replacing manual bidirectional `AllowList()` calls. This change
reduces verbosity and ensures consistency in how links are established
in the test topology.
2026-04-17 13:22:27 -05:00

940 lines
36 KiB
C++
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/*
* Copyright (c) 2026, The OpenThread Authors.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdio.h>
#include "platform/nexus_core.hpp"
#include "platform/nexus_node.hpp"
namespace ot {
namespace Nexus {
/**
* Time to advance for a node to form a network and become leader, in milliseconds.
*/
static constexpr uint32_t kFormNetworkTime = 20 * 1000;
/**
* Time to advance for a node to join as a child and upgrade to a router, in milliseconds.
*/
static constexpr uint32_t kJoinNetworkTime = 300 * 1000;
/**
* Time to advance for the BR to perform automatic actions (RA, Network Data), in milliseconds.
*/
static constexpr uint32_t kBrActionTime = 100 * 1000;
/**
* Longer time to advance for network stabilization and address configuration.
*/
static constexpr uint32_t kLongActionTime = 500 * 1000;
/**
* Time to advance for the ping response, in milliseconds.
*/
static constexpr uint32_t kPingResponseTime = 100 * 1000;
/**
* Default Hop Limit for Echo Request.
*/
static constexpr uint8_t kDefaultHopLimit = 64;
/**
* Infrastructure interface index.
*/
static constexpr uint32_t kInfraIfIndex = 1;
/**
* Echo Request identifier.
*/
static constexpr uint16_t kEchoIdentifier = 0x1234;
/**
* Echo Request payload size.
*/
static constexpr uint16_t kEchoPayloadSize = 10;
/**
* Max number of seconds to wait for a condition.
*/
static constexpr uint32_t kMaxWaitTime = 120;
/**
* OMR prefix 3 string (numerically very low to be "winning").
*/
static constexpr char kOmr3PrefixStr[] = "fd00:3::/64";
/**
* OMR prefix 4 string (numerically very high to be "losing" if same preference).
*/
static constexpr char kOmr4PrefixStr[] = "fdff:4::/64";
/**
* Infrastructure GUA address string for Eth_1.
*/
static constexpr char kEth1GuaAddrStr[] = "2001:db8:1::1";
/**
* Infrastructure GUA prefix string.
*/
static constexpr char kGua1PrefixStr[] = "2001:db8:1::/64";
static void DumpNetworkData(Node &aNode)
{
NetworkData::Iterator iterator = NetworkData::kIteratorInit;
NetworkData::OnMeshPrefixConfig prefixConfig;
NetworkData::ExternalRouteConfig routeConfig;
Log("Network Data for %s (Version: %d):", aNode.GetName(),
aNode.Get<NetworkData::Leader>().GetVersion(NetworkData::kFullSet));
while (aNode.Get<NetworkData::Leader>().GetNext(iterator, prefixConfig) == kErrorNone)
{
Log(" Prefix: %s (pref:%d, preferred:%s)", prefixConfig.GetPrefix().ToString().AsCString(),
prefixConfig.mPreference, ToYesNo(prefixConfig.mPreferred));
}
iterator = NetworkData::kIteratorInit;
while (aNode.Get<NetworkData::Leader>().GetNext(iterator, routeConfig) == kErrorNone)
{
Log(" Route: %s (pref:%d)", routeConfig.GetPrefix().ToString().AsCString(), routeConfig.mPreference);
}
}
static bool HasNetDataPrefix(Node &aNode, const Ip6::Prefix &aPrefix)
{
return aNode.Get<NetworkData::Leader>().ContainsOmrPrefix(aPrefix);
}
static bool HasNetDataRoute(Node &aNode, const char *aPrefixStr)
{
bool hasRoute = false;
NetworkData::Iterator iterator = NetworkData::kIteratorInit;
NetworkData::ExternalRouteConfig routeConfig;
Ip6::Prefix target;
SuccessOrQuit(target.FromString(aPrefixStr));
while (aNode.Get<NetworkData::Leader>().GetNext(iterator, routeConfig) == kErrorNone)
{
if (AsCoreType(&routeConfig.mPrefix) == target)
{
hasRoute = true;
break;
}
}
return hasRoute;
}
static void WaitForPrefix(Core &aNexus, Node &aNode, const Ip6::Prefix &aPrefix, bool aPresent)
{
for (uint32_t i = 0; i < kMaxWaitTime; i++)
{
if (HasNetDataPrefix(aNode, aPrefix) == aPresent)
{
break;
}
aNexus.AdvanceTime(1000);
}
VerifyOrQuit(HasNetDataPrefix(aNode, aPrefix) == aPresent);
}
static void WaitForRoute(Core &aNexus, Node &aNode, const char *aPrefixStr, bool aPresent)
{
for (uint32_t i = 0; i < kMaxWaitTime; i++)
{
if (HasNetDataRoute(aNode, aPrefixStr) == aPresent)
{
break;
}
aNexus.AdvanceTime(1000);
}
VerifyOrQuit(HasNetDataRoute(aNode, aPrefixStr) == aPresent);
}
static void PublishOmrPrefix(Node &aNode,
const Ip6::Prefix &aPrefix,
NetworkData::RoutePreference aPreference,
bool aIsPreferred)
{
NetworkData::OnMeshPrefixConfig config;
config.Clear();
config.GetPrefix() = aPrefix;
config.mPreference = aPreference;
config.mSlaac = true;
config.mOnMesh = true;
config.mStable = true;
config.mPreferred = aIsPreferred;
SuccessOrQuit(aNode.Get<NetworkData::Publisher>().PublishOnMeshPrefix(config, NetworkData::Publisher::kFromUser));
}
void Test_1_3_DBR_TC_8(void)
{
/**
* 1.8. [1.3] [CERT] Reachability - Multiple BRs - Single Thread / Single IPv6 Infrastructure - OMR prefix selection
*
* 1.8.1. Purpose
* - To test the following:
* - Maintain bi-directional reachability between Thread devices and infrastructure devices during prefix changes
* - DUT BR should observe proper OMR prefix selection when testbed-BR advertises various other prefixes:
* - Testbed advertises a winning prefix with equal preference, DUT should withdraw or deprecate its OMR prefix
* - Testbed advertises a numerically higher, non-winning prefix with equal preference, DUT should not change
* behavior.
* - Testbed advertises a numerically higher prefix with higher preference, i.e. winning OMR prefix, DUT should
* withdraw its OMR prefix.
* - Testbed withdraws winning OMR prefix, DUT should advertise its prefix with 'Low' preference again
* - Testbed OMR prefix becomes deprecated, DUT should advertise its prefix with 'Low' preference again
*
* 1.8.2. Topology
* - Eth_1 - Adjacent Infrastructure Link Reference Device
* - BR_1 (DUT) - Border Router
* - BR_2 - Border Router Reference Device and Leader
* - ED_1 - Thread Reference Device (End Device) attached to BR_1
*
* Spec Reference | V1.1 Section | V1.3.0 Section
* -----------------|--------------|---------------
* Reachability | N/A | 1.3
*/
Core nexus;
Node &eth1 = nexus.CreateNode();
Node &br1 = nexus.CreateNode();
Node &br2 = nexus.CreateNode();
Node &ed1 = nexus.CreateNode();
eth1.SetName("Eth_1");
br1.SetName("BR_1");
br2.SetName("BR_2");
ed1.SetName("ED_1");
nexus.AdvanceTime(0);
SuccessOrQuit(Instance::SetGlobalLogLevel(kLogLevelNote));
Log("---------------------------------------------------------------------------------------");
/**
* Step 0
* - Device: Eth_1
* - Description (DBR-1.8):
* - Harness configures Ethernet link with an on-link IPv6 GUA prefix GUA_1. Eth_1 is configured to multicast ND
* RAs.
* - Automatically configures a global address “Eth_1 GUA”.
* - Pass Criteria
* - N/A
*/
Log("Step 0: Eth_1 configured with GUA_1.");
Ip6::Address eth1Gua;
SuccessOrQuit(eth1Gua.FromString(kEth1GuaAddrStr));
eth1.mInfraIf.AddAddress(eth1Gua);
Ip6::Prefix gua1;
SuccessOrQuit(gua1.FromString(kGua1PrefixStr));
eth1.mInfraIf.StartRouterAdvertisement(gua1);
nexus.AddTestVar("ETH_1_GUA_ADDR", kEth1GuaAddrStr);
Log("---------------------------------------------------------------------------------------");
/**
* Step 1
* - Device: Eth_1, BR_2, ED_1, ED_2
* - Description (DBR-1.8):
* - Enable; BR_2 automatically configures an OMR prefix for the mesh, OMR_1. Harness records the value of OMR_1
* and saves it for verification use.
* - Note: the OT command ‘br omrprefix’ should provide the prefix from BR_2.
* - Form topology. Wait for BR_2 to:
* - Become Leader
* - Register as border router in Thread Network Data with its OMR prefix OMR_1
* - Send multicast ND RAs on AIL
* - Automatically advertise a route to GUA_1 in the Thread Network Data, using a Prefix TLV:
* - Prefix = ::/0
* - Domain ID = <self-selected value>
* - Has Route sub-TLV
* - Pass Criteria
* - N/A
*/
Log("Step 1: BR_2 becomes Leader and registers OMR_1.");
AllowLinkBetween(br1, br2);
AllowLinkBetween(br1, ed1);
br2.Form();
nexus.AdvanceTime(kFormNetworkTime);
br2.Get<BorderRouter::InfraIf>().Init(kInfraIfIndex, true);
br2.Get<BorderRouter::RoutingManager>().Init();
SuccessOrQuit(br2.Get<BorderRouter::RoutingManager>().SetEnabled(true));
nexus.AdvanceTime(kBrActionTime);
WaitForRoute(nexus, br2, "::/0", true);
Ip6::Prefix omr1;
SuccessOrQuit(br2.Get<BorderRouter::RoutingManager>().GetOmrPrefix(omr1));
nexus.AddTestVar("OMR_1_PREFIX", omr1.ToString().AsCString());
Log("OMR_1_PREFIX: %s", omr1.ToString().AsCString());
DumpNetworkData(br2);
Log("---------------------------------------------------------------------------------------");
/**
* Step 2
* - Device: BR_1 (DUT)
* - Description (DBR-1.8): Enable: switch on.
* - Pass Criteria
* - N/A
*/
Log("Step 2: Enable BR_1 (DUT).");
br1.Join(br2);
nexus.AdvanceTime(kJoinNetworkTime);
br1.Get<BorderRouter::InfraIf>().Init(kInfraIfIndex, true);
br1.Get<BorderRouter::RoutingManager>().Init();
SuccessOrQuit(br1.Get<BorderRouter::RoutingManager>().SetEnabled(true));
Log("---------------------------------------------------------------------------------------");
/**
* Step 3
* - Device: BR_1 (DUT)
* - Description (DBR-1.8):
* - Automatically registers itself as a border router in the Thread Network Data.
* - Pass Criteria:
* - The DUT MUST register a route to GUA_1 in the Thread Network Data as follows:
* - Prefix TLV: Prefix = ::/0
* - Domain ID = <same value as that of BR_2 in step 1>
* - Has Route sub-TLV
* - R_preference = 00 (medium) or 11 (low)
* - DUT MUST NOT register an OMR prefix (e.g. OMR_1, or other) in Thread Network Data.
*/
Log("Step 3: BR_1 (DUT) registers route to GUA_1.");
nexus.AdvanceTime(kBrActionTime);
DumpNetworkData(br2);
Log("---------------------------------------------------------------------------------------");
/**
* Step 4
* - Device: BR_1 (DUT)
* - Description (DBR-1.8):
* - Automatically announces the route to OMR_1 on the AIL.
* - Pass Criteria:
* - The DUT MUST multicast ND RAs on the infrastructure link:
* - IPv6 destination MUST be ff02::1
* - MUST NOT contain a Prefix Information Option (PIO) with a ULA prefix.
* - MUST contain a Route Information Option (RIO) with OMR_1.
* - "Prf" bits MUST be 00 (medium) or 11 (low)
*/
Log("Step 4: BR_1 (DUT) announces OMR_1 on AIL.");
nexus.AdvanceTime(kBrActionTime);
Log("---------------------------------------------------------------------------------------");
/**
* Step 5
* - Device: BR_2
* - Description (DBR-1.8):
* - Harness instructs device to remove the existing OMR prefix (OMR_1) being advertised and send out new network
* data without any prefix.
* - Note: for 1.3.x cert, this could be implemented by 'br disable' or 'netdata unpublish <OMR_1>' on BR_2.
* - Pass Criteria:
* - N/A
*/
Log("Step 5: BR_2 removes OMR_1.");
SuccessOrQuit(br2.Get<BorderRouter::RoutingManager>().SetEnabled(false));
WaitForPrefix(nexus, br2, omr1, false);
nexus.AdvanceTime(kBrActionTime);
DumpNetworkData(br2);
Log("---------------------------------------------------------------------------------------");
/**
* Step 6
* - Device: BR_1 (DUT)
* - Description (DBR-1.8):
* - Automatically chooses a new OMR prefix OMR_2 and includes it in the Network Data.
* - Pass Criteria:
* - The DUT MUST register a new OMR prefix (OMR_2) in the Thread Network Data using Prefix TLV as follows:
* - Prefix = OMR_2
* - Border Router sub-TLV
* - P_preference = 11 (Low)
* - P_default = true
* - P_stable = true
* - P_on_mesh = true
* - P_preferred = true
* - P_slaac = true
* - P_dhcp = false
* - P_dp = false
* - OMR_2 MUST be 64 bits long and start with 0xFD.
* - OMR_2 MUST differ from OMR_1.
* - Also MUST contain a Prefix TLV as follows:
* - Prefix = ::/0
* - Domain ID <same value as BR_2 Domain ID>
* - Has Route TLV
* - R_preference = 00 (medium) or 11 (low)
* - Note: one possible way to check this is to verify the contents of the SVR_DATA.ntf message sent by DUT to
* Leader.
*/
Log("Step 6: BR_1 (DUT) chooses OMR_2 and registers in Network Data.");
nexus.AdvanceTime(kBrActionTime);
Ip6::Prefix omr2;
SuccessOrQuit(br1.Get<BorderRouter::RoutingManager>().GetOmrPrefix(omr2));
VerifyOrQuit(omr2 != omr1);
nexus.AddTestVar("OMR_2_PREFIX", omr2.ToString().AsCString());
Log("OMR_2_PREFIX: %s", omr2.ToString().AsCString());
DumpNetworkData(br2);
Log("---------------------------------------------------------------------------------------");
/**
* Step 7
* - Device: BR_1 (DUT)
* - Description (DBR-1.8):
* - Automatically multicasts ND RAs on Adjacent Infrastructure Link.
* - Pass Criteria:
* - The DUT MUST multicast ND RAs on the infrastructure link:
* - IPv6 destination MUST be ff02::1
* - MUST NOT contain a Prefix Information Option (PIO) with a ULA prefix.
* - MUST contain a Route Information Option (RIO) with OMR_2.
* - "Prf" bits MUST be 00 (medium) or 11 (low).
* - MUST NOT contain a Route Information Option (RIO) with OMR_1.
*/
Log("Step 7: BR_1 (DUT) multicasts ND RA with OMR_2, no OMR_1.");
nexus.AdvanceTime(kBrActionTime);
Log("---------------------------------------------------------------------------------------");
/**
* Step 8
* - Device: Eth_1
* - Description (DBR-1.8):
* - Harness instructs the device to send an ICMPv6 Echo Request to ED_1 via either one of BR_1 or BR_2.
* - IPv6 Source: Eth_1 GUA
* - IPv6 Destination: ED_1 OMR address (using prefix OMR_2)
* - Pass Criteria:
* - Eth_1 receives an ICMPv6 Echo Reply from ED_1.
* - IPv6 Source: ED_1 OMR (using prefix OMR_2)
* - IPv6 Destination: Eth_1 GUA
*/
Log("Step 8: Eth_1 pings ED_1 OMR_2.");
ed1.Join(br1, Node::kAsFed);
nexus.AdvanceTime(kJoinNetworkTime);
const Ip6::Address &ed1Omr2 = ed1.FindMatchingAddress(omr2.ToString().AsCString());
nexus.AddTestVar("ED_1_OMR_2_ADDR", ed1Omr2.ToString().AsCString());
eth1.mInfraIf.SendEchoRequest(eth1Gua, ed1Omr2, kEchoIdentifier, kEchoPayloadSize);
nexus.AdvanceTime(kPingResponseTime);
Log("---------------------------------------------------------------------------------------");
/**
* Step 9
* - Device: ED_1
* - Description (DBR-1.8):
* - Harness instructs the device to send an ICMPv6 Echo Request to Eth_1.
* - IPv6 Source: ED_1 OMR address (using prefix OMR_2)
* - IPv6 Destination: Eth_1 GUA
* - Pass Criteria:
* - ED_1 receives an ICMPv6 Echo Reply from Eth_1.
* - IPv6 Source: Eth_1 GUA
* - IPv6 Destination: ED_1 OMR address (using prefix OMR_2)
*/
Log("Step 9: ED_1 OMR_2 pings Eth_1 GUA.");
ed1.SendEchoRequest(eth1Gua, kEchoIdentifier, kEchoPayloadSize, kDefaultHopLimit, &ed1Omr2);
nexus.AdvanceTime(kPingResponseTime);
Log("---------------------------------------------------------------------------------------");
/**
* Step 10
* - Device: BR_2
* - Description (DBR-1.8):
* - Harness instructs BR_2 to add an OMR prefix OMR_3 numerically lower than OMR_2, but with same preference
* "Low".
* - Note: can use OT command 'netdata publish prefix' for this.
* - Pass Criteria:
* - N/A
*/
Log("Step 10: BR_2 adds OMR_3.");
Ip6::Prefix omr3;
SuccessOrQuit(omr3.FromString(kOmr3PrefixStr));
PublishOmrPrefix(br2, omr3, NetworkData::kRoutePreferenceLow, true);
nexus.AdvanceTime(kLongActionTime);
WaitForPrefix(nexus, br2, omr3, true);
DumpNetworkData(br2);
nexus.AddTestVar("OMR_3_PREFIX", kOmr3PrefixStr);
Log("OMR_3_PREFIX: %s", kOmr3PrefixStr);
Log("---------------------------------------------------------------------------------------");
/**
* Step 11
* - Device: BR_1 (DUT)
* - Description (DBR-1.8):
* - Automatically withdraws its own OMR prefix OMR_2 from the Thread Network Data.
* - Pass Criteria:
* - The DUT MUST register new Network Data:
* - MUST NOT contain any of the OMR prefixes OMR_1, OMR_2, or OMR_3 in a Prefix TLV.
* - MUST contain a Prefix TLV:
* - Prefix = ::/0
* - Domain ID <same value as BR_2 Domain ID>
* - Has Route TLV
* - R_preference = 00 (medium) or 11 (low)
*/
Log("Step 11: BR_1 (DUT) withdraws OMR_2 from Network Data.");
WaitForPrefix(nexus, br2, omr2, false);
nexus.AdvanceTime(kLongActionTime);
DumpNetworkData(br2);
Log("---------------------------------------------------------------------------------------");
/**
* Step 12
* - Device: BR_1 (DUT)
* - Description (DBR-1.8):
* - Automatically multicasts ND RAs on Adjacent Infrastructure Link including OMR_2/OMR_3.
* - Note: the reason that OMR_2 is still included initially, is that OMR_2 has been created by BR_1 originally
* and as seen by BR_1, it stays in a deprecated state for at most OMR_ADDR_DEPRECATION_TIME
* - Pass Criteria:
* - The DUT MUST multicast ND RAs on the infrastructure link:
* - IPv6 destination MUST be ff02::1
* - MUST NOT contain a Prefix Information Option (PIO) with a ULA prefix.
* - MUST NOT contain a Route Information Option (RIO) with OMR_1.
* - MUST contain a Route Information Option (RIO) with OMR_2.
* - "Prf" bits MUST be 00 (medium) or 11 (low)
* - MUST contain a Route Information Option (RIO) with OMR_3.
* - "Prf" bits MUST be 00 (medium) or 11 (low)
*/
Log("Step 12: BR_1 (DUT) multicasts ND RA with OMR_2 and OMR_3.");
nexus.AdvanceTime(kBrActionTime);
DumpNetworkData(br1);
DumpNetworkData(br2);
Log("---------------------------------------------------------------------------------------");
/**
* Step 13
* - Device: Eth_1
* - Description (DBR-1.8):
* - Harness instructs the device to send an ICMPv6 Echo Request to ED_1 via BR_1 or BR_2.
* - IPv6 Source: Eth_1 GUA
* - IPv6 Destination: ED_1 OMR address (using prefix OMR_3)
* - Pass Criteria:
* - Eth_1 receives an ICMPv6 Echo Reply from ED_1.
* - IPv6 Source: ED_1 OMR (using prefix OMR_3)
* - IPv6 Destination: Eth_1 GUA
*/
Log("Step 13: Eth_1 pings ED_1 OMR_3.");
const Ip6::Address &ed1Omr3 = ed1.FindMatchingAddress(kOmr3PrefixStr);
nexus.AddTestVar("ED_1_OMR_3_ADDR", ed1Omr3.ToString().AsCString());
eth1.mInfraIf.SendEchoRequest(eth1Gua, ed1Omr3, kEchoIdentifier, kEchoPayloadSize);
nexus.AdvanceTime(kPingResponseTime);
Log("---------------------------------------------------------------------------------------");
/**
* Step 14
* - Device: ED_1
* - Description (DBR-1.8):
* - Harness instructs the device to send an ICMPv6 Echo Request to Eth_1.
* - IPv6 Source: ED_1 OMR address (using prefix OMR_3)
* - IPv6 Destination: Eth_1 GUA
* - Pass Criteria:
* - ED_1 receives an ICMPv6 Echo Reply from Eth_1.
* - IPv6 Source: Eth_1 GUA
* - IPv6 Destination: ED_1 OMR address (using prefix OMR_3)
*/
Log("Step 14: ED_1 OMR_3 pings Eth_1 GUA.");
ed1.SendEchoRequest(eth1Gua, kEchoIdentifier, kEchoPayloadSize, kDefaultHopLimit, &ed1Omr3);
nexus.AdvanceTime(kPingResponseTime);
Log("---------------------------------------------------------------------------------------");
/**
* Step 15
* - Device: BR_2
* - Description (DBR-1.8):
* - Harness instructs device to remove existing OMR prefix (OMR_3) that is being advertised and sends out new
* network data without the prefix OMR_3.
* - Note: can use OT command 'netdata unpublish <prefix>' for this.
* - Pass Criteria:
* - N/A
*/
Log("Step 15: BR_2 removes OMR_3.");
SuccessOrQuit(br2.Get<NetworkData::Publisher>().UnpublishPrefix(omr3));
WaitForPrefix(nexus, br2, omr3, false);
nexus.AdvanceTime(kLongActionTime);
DumpNetworkData(br2);
Log("---------------------------------------------------------------------------------------");
/**
* Step 16
* - Device: BR_1 (DUT)
* - Description (DBR-1.8):
* - Automatically starts advertising its own OMR prefix OMR_2 again.
* - Pass Criteria:
* - The DUT MUST register its OMR prefix OMR_2 in the Thread Network Data. Flags in the Border Router sub-TLV
* MUST be:
* - P_preference = 11 (Low)
* - P_default = true
* - P_stable = true
* - P_on_mesh = true
* - P_preferred = true
* - P_slaac = true
* - P_dhcp = false
* - P_dp = false
* - OMR_2 MUST be 64 bits long and start with 0xFD.
* - OMR_2 MUST be equal to the OMR_2 values as used in previous test steps.
*/
Log("Step 16: BR_1 (DUT) re-registers OMR_2.");
WaitForPrefix(nexus, br2, omr2, true);
nexus.AdvanceTime(kBrActionTime);
DumpNetworkData(br2);
Log("---------------------------------------------------------------------------------------");
/**
* Step 17
* - Device: BR_1 (DUT)
* - Description (DBR-1.8):
* - Automatically multicasts ND RAs on Adjacent Infrastructure Link with OMR_2.
* - Note: the reason that OMR_3 is not advertised, is that OMR_3 was withdrawn and was not originally created by
* BR_1. So BR_1 has no responsibility to advertise this deprecated prefix.
* - Pass Criteria:
* - The DUT MUST multicast ND RAs on the infrastructure link:
* - IPv6 destination MUST be ff02::1
* - MUST NOT contain a Prefix Information Option (PIO) with a ULA prefix.
* - MUST NOT contain a Route Information Option (RIO) with OMR_1.
* - MUST contain a Route Information Option (RIO) with OMR_2.
* - "Prf" bits MUST be 00 (medium) or 11 (low)
* - MUST NOT contain a Route Information Option (RIO) with OMR_3.
*/
Log("Step 17: BR_1 (DUT) multicasts ND RA with OMR_2, no OMR_3.");
nexus.AdvanceTime(kBrActionTime);
Log("---------------------------------------------------------------------------------------");
/**
* Step 18
* - Device: BR_2
* - Description (DBR-1.8):
* - Harness instructs the device to add new OMR prefix (OMR_4) numerically higher than OMR_2, but with same
* preference "Low".
* - Pass Criteria:
* - N/A
*/
Log("Step 18: BR_2 adds OMR_4.");
Ip6::Prefix omr4;
SuccessOrQuit(omr4.FromString(kOmr4PrefixStr));
PublishOmrPrefix(br2, omr4, NetworkData::kRoutePreferenceLow, true);
WaitForPrefix(nexus, br2, omr4, true);
nexus.AdvanceTime(kLongActionTime);
nexus.AddTestVar("OMR_4_PREFIX", kOmr4PrefixStr);
Log("OMR_4_PREFIX: %s", kOmr4PrefixStr);
DumpNetworkData(br2);
Log("---------------------------------------------------------------------------------------");
/**
* Step 19
* - Device: BR_1 (DUT)
* - Description (DBR-1.8):
* - No change in behavior for advertising its OMR prefix, OMR_2.
* - Automatically starts advertising a route for the new OMR_4 prefix.
* - Pass Criteria:
* - The DUT MUST NOT send a Network Data update with any one of the following prefixes in a Prefix TLV:
* - OMR_1, OMR_2, OMR_3, OMR_4
* - The DUT MUST multicast ND RAs on the infrastructure link:
* - IPv6 destination MUST be ff02::1
* - MUST NOT contain a Prefix Information Option (PIO) with a ULA prefix.
* - MUST contain a Route Information Option (RIO) with OMR_2.
* - "Prf" bits MUST be 00 (medium) or 11 (low).
* - MUST contain a Route Information Option (RIO) with OMR_4.
* - "Prf" bits MUST be 00 (medium) or 11 (low).
* - MUST NOT contain RIO with any one of OMR_1, OMR_3.
*/
Log("Step 19: BR_1 (DUT) continues OMR_2, adds OMR_4 on AIL.");
nexus.AdvanceTime(kBrActionTime);
DumpNetworkData(br2);
Log("---------------------------------------------------------------------------------------");
/**
* Step 20
* - Device: BR_2
* - Description (DBR-1.8):
* - Harness instructs the device to update the numerically higher OMR_4 with a higher preference value 00
* ('Medium').
* - Pass Criteria:
* - N/A
*/
Log("Step 20: BR_2 updates OMR_4 to Medium pref.");
PublishOmrPrefix(br2, omr4, NetworkData::kRoutePreferenceMedium, true);
nexus.AdvanceTime(kLongActionTime);
DumpNetworkData(br2);
Log("---------------------------------------------------------------------------------------");
/**
* Step 21
* - Device: BR_1 (DUT)
* - Description (DBR-1.8): Automatically withdraws its current OMR prefix OMR_2.
* - Pass Criteria:
* - The DUT MUST send a Network Data update. In the new network data:
* - the following prefixes MUST NOT be present in a Prefix TLV: OMR_1, OMR_2, OMR_3
* - The DUT MUST multicast ND RAs on the infrastructure link:
* - IPv6 destination MUST be ff02::1
* - MUST NOT contain a Prefix Information Option (PIO) with a ULA prefix.
* - MUST contain a Route Information Option (RIO) with OMR_2:
* - "Prf" bits MUST be 00 (medium) or 11 (low).
* - MUST contain a Route Information Option (RIO) with OMR_4:
* - "Prf" bits MUST be 00 (medium) or 11 (low).
* - MUST NOT contain a Route Information Option (RIO) with OMR_1 or OMR_3.
*/
Log("Step 21: BR_1 (DUT) withdraws OMR_2.");
WaitForPrefix(nexus, br2, omr2, false);
nexus.AdvanceTime(kBrActionTime);
DumpNetworkData(br2);
Log("---------------------------------------------------------------------------------------");
/**
* Step 22
* - Device: BR_2
* - Description (DBR-1.8):
* - Harness instructs the device to update the prefix OMR_4 to a deprecated state by setting P_preferred =
* 'false'.
* - Note: can use OT command 'netdata publish prefix' for this where the flags do not contain the 'p' (Preferred)
* flag.
* - Pass Criteria:
* - N/A
*/
Log("Step 22: BR_2 deprecates OMR_4.");
PublishOmrPrefix(br2, omr4, NetworkData::kRoutePreferenceMedium, false);
nexus.AdvanceTime(kLongActionTime);
DumpNetworkData(br2);
Log("---------------------------------------------------------------------------------------");
/**
* Step 23
* - Device: BR_1 (DUT)
* - Description (DBR-1.8): Automatically starts advertising its own OMR prefix OMR_2 again.
* - Pass Criteria:
* - The DUT MUST register its OMR prefix OMR_2 in the Thread Network Data. Flags in the Border Router sub-TLV
* MUST be:
* - P_preference = 11 (Low)
* - P_default = true
* - P_stable = true
* - P_on_mesh = true
* - P_preferred = true
* - P_slaac = true
* - P_dhcp = false
* - P_dp = false
* - OMR_2 MUST be 64 bits long and start with 0xFD.
* - OMR_2 MUST be equal to the OMR_2 values as used in previous test steps.
*/
Log("Step 23: BR_1 (DUT) re-registers OMR_2.");
WaitForPrefix(nexus, br2, omr2, true);
nexus.AdvanceTime(kBrActionTime);
DumpNetworkData(br2);
Log("---------------------------------------------------------------------------------------");
/**
* Step 24
* - Device: BR_1 (DUT)
* - Description (DBR-1.8):
* - Automatically multicasts ND RAs on Adjacent Infrastructure Link.
* - Note: even though OMR_4 is deprecated, it is still valid so it is advertised on the AIL in a RIO.
* - Pass Criteria:
* - The DUT MUST multicast ND RAs on the infrastructure link:
* - IPv6 destination MUST be ff02::1
* - MUST NOT contain a Prefix Information Option (PIO) with a ULA prefix.
* - MUST NOT contain a Route Information Option (RIO) with OMR_1.
* - MUST contain a Route Information Option (RIO) with OMR_2.
* - "Prf" bits MUST be 00 (medium) or 11 (low)
* - MUST NOT contain a Route Information Option (RIO) with OMR_3.
* - MUST contain a Route Information Option (RIO) with OMR_4.
* - "Prf" bits MUST be 00 (medium) or 11 (low)
*/
Log("Step 24: BR_1 (DUT) multicasts ND RA with OMR_2 and OMR_4.");
nexus.AdvanceTime(kBrActionTime);
Log("---------------------------------------------------------------------------------------");
/**
* Step 25
* - Device: Eth_1
* - Description (DBR-1.8):
* - Harness instructs the device to send an ICMPv6 Echo Request to ED_1 via BR_1.
* - IPv6 Source: Eth_1 GUA
* - IPv6 Destination: ED_1 OMR address (using prefix OMR_2)
* - Pass Criteria:
* - Eth_1 receives an ICMPv6 Echo Reply from ED_1.
* - IPv6 Source: ED_1 OMR (using prefix OMR_2)
* - IPv6 Destination: Eth_1 GUA
*/
Log("Step 25: Eth_1 pings ED_1 OMR_2.");
eth1.mInfraIf.SendEchoRequest(eth1Gua, ed1Omr2, kEchoIdentifier, kEchoPayloadSize);
nexus.AdvanceTime(kPingResponseTime);
Log("---------------------------------------------------------------------------------------");
/**
* Step 26
* - Device: ED_1
* - Description (DBR-1.8):
* - Harness instructs the device to send an ICMPv6 Echo Request to Eth_1.
* - IPv6 Source: ED_1 OMR address (using prefix OMR_2)
* - IPv6 Destination: Eth_1 GUA
* - Pass Criteria:
* - ED_1 receives an ICMPv6 Echo Reply from Eth_1.
* - IPv6 Source: Eth_1 GUA
* - IPv6 Destination: ED_1 OMR address (using prefix OMR_2)
*/
Log("Step 26: ED_1 OMR_2 pings Eth_1 GUA.");
ed1.SendEchoRequest(eth1Gua, kEchoIdentifier, kEchoPayloadSize, kDefaultHopLimit, &ed1Omr2);
nexus.AdvanceTime(kPingResponseTime);
Log("---------------------------------------------------------------------------------------");
/**
* Step 27
* - Device: BR_2
* - Description (DBR-1.8):
* - Harness disables the BR function of the device. Or if that is not possible, switch it off.
* - Note: disabling BR may use 'br disable' CLI command.
* - Note: in case of switching off BR_2, the OMR prefix OMR_4 that was advertised by BR_2 remains active for some
* time. The Leader timeout of Leader BR_2 does not happen yet during the below steps of this test.
* - Pass Criteria:
* - N/A
*/
Log("Step 27: BR_2 disabled.");
SuccessOrQuit(br2.Get<BorderRouter::RoutingManager>().SetEnabled(false));
nexus.AdvanceTime(kBrActionTime);
DumpNetworkData(br2);
Log("---------------------------------------------------------------------------------------");
/**
* Step 28
* - Device: Eth_1
* - Description (DBR-1.8):
* - Harness instructs the device to send an ICMPv6 Echo Request to ED_1 via BR_1.
* - IPv6 Source: Eth_1 GUA
* - IPv6 Destination: ED_1 OMR address (using prefix OMR_2)
* - Pass Criteria:
* - Eth_1 receives an ICMPv6 Echo Reply from ED_1.
* - IPv6 Source: ED_1 OMR (using prefix OMR_2)
* - IPv6 Destination: Eth_1 GUA
*/
Log("Step 28: Eth_1 pings ED_1 OMR_2.");
eth1.mInfraIf.SendEchoRequest(eth1Gua, ed1Omr2, kEchoIdentifier, kEchoPayloadSize);
nexus.AdvanceTime(kPingResponseTime);
Log("---------------------------------------------------------------------------------------");
/**
* Step 29
* - Device: ED_1
* - Description (DBR-1.8):
* - Harness instructs the device to send an ICMPv6 Echo Request to Eth_1.
* - IPv6 Source: ED_1 OMR address (using prefix OMR_4)
* - IPv6 Destination: Eth_1 GUA.
* - Note: ED_1 is forced here to use a source address based on prefix OMR_4, even though that prefix is
* deprecated. In OT CLI this can most likely be achieved using the command:
* - ping -I <ED_1-OMR_4-address> <Eth_1-GUA>
* - Pass Criteria:
* - N/A
*/
Log("Step 29: ED_1 pings Eth_1 using OMR_4.");
const Ip6::Address &ed1Omr4 = ed1.FindMatchingAddress(kOmr4PrefixStr);
nexus.AddTestVar("ED_1_OMR_4_ADDR", ed1Omr4.ToString().AsCString());
ed1.SendEchoRequest(eth1Gua, kEchoIdentifier, kEchoPayloadSize, kDefaultHopLimit, &ed1Omr4);
Log("---------------------------------------------------------------------------------------");
/**
* Step 30
* - Device: Eth_1
* - Description (DBR-1.8):
* - Automatically replies to the ICMPv6 Echo Request with Echo Reply, that is sent to BR_1.
* - Pass Criteria:
* - N/A
*/
Log("Step 30: Eth_1 replies to OMR_4.");
nexus.AdvanceTime(kPingResponseTime);
Log("---------------------------------------------------------------------------------------");
/**
* Step 31
* - Device: BR_1 (DUT)
* - Description (DBR-1.8):
* - Automatically attempts to deliver the Echo Reply to a node on the mesh.
* - Pass Criteria:
* - The DUT MUST attempt to deliver the packet to a node on the mesh, either:
* - 1. BR_1 sends a multicast Address Query for ED_1 OMR_4 based address into the mesh;
* - 2. or ED_1 receives the Echo Reply from Eth_1 as follows:
* - IPv6 Source: Eth_1 GUA
* - IPv6 Destination: ED_1 OMR address (using prefix OMR_4)
*/
Log("Step 31: BR_1 delivers Echo Reply for OMR_4.");
nexus.AdvanceTime(kPingResponseTime);
nexus.SaveTestInfo("test_1_3_DBR_TC_8.json");
}
} // namespace Nexus
} // namespace ot
int main(void)
{
ot::Nexus::Test_1_3_DBR_TC_8();
printf("All tests passed\n");
return 0;
}