[nexus] add MATN-TC-07 test case for BBR multicast forwarding (#12694)

This commit implements the MATN-TC-07 test case in the Nexus
simulation framework to verify default multicast forwarding
behavior on Border Routers.

Key implementation details include:
- Implementation of the MATN-TC-07 test scenario in C++ to
  trigger various multicast ping requests across different
  IPv6 scopes (realm-local, admin-local, site-local, global,
  and link-local).
- Enhancement of the Python verification script to strictly
  validate that only the Primary BBR forwards multicast
  packets to the backbone link using Ethernet source address
  filtering.
- Support for Ethernet link type in Nexus PCAP generation by
  prepending Ethernet headers to infrastructure IPv6 packets.
- Exposure of infrastructure MAC addresses (ethaddrs) in the
  test information JSON to enable identification of the
  forwarding node on the backbone link.
- Support for verifying source addresses of MPL-encapsulated
  multicast packets by checking both outer and inner headers.
- Addition of FindGlobalAddress() helper in the Nexus node
  platform.
This commit is contained in:
Jonathan Hui
2026-03-16 20:35:22 -05:00
committed by GitHub
parent 725b101150
commit 0f44bd990e
11 changed files with 910 additions and 22 deletions
+29
View File
@@ -164,8 +164,17 @@ void Node::HandleReceive(otMessage *aMessage)
Core::Get().SetActiveNode(this);
if (header->GetDestination().IsMulticast())
{
VerifyOrExit(Get<BackboneRouter::Local>().IsPrimary());
}
VerifyOrExit(Get<NetworkData::Leader>().IsOnMesh(header->GetSource()));
// Only forward if source is NOT Link-Local and NOT Mesh-Local.
VerifyOrExit(!header->GetSource().IsLinkLocalUnicastOrMulticast());
VerifyOrExit(!Get<Mle::Mle>().IsMeshLocalAddress(header->GetSource()));
mInfraIf.SendIp6(header->GetSource(), header->GetDestination(), buffer, length);
exit:
@@ -201,5 +210,25 @@ const Ip6::Address &Node::FindMatchingAddress(const char *aPrefix)
return *matchedAddress;
}
const Ip6::Address &Node::FindGlobalAddress(void)
{
const Ip6::Address *matchedAddress = nullptr;
for (const Ip6::Netif::UnicastAddress &unicastAddress : Get<ThreadNetif>().GetUnicastAddresses())
{
const Ip6::Address &address = unicastAddress.GetAddress();
if (address.GetScope() == Ip6::Address::kGlobalScope && !Get<Mle::Mle>().IsMeshLocalAddress(address))
{
matchedAddress = &address;
break;
}
}
VerifyOrQuit(matchedAddress != nullptr, "no global address found");
return *matchedAddress;
}
} // namespace Nexus
} // namespace ot