diff --git a/src/core/net/ip6.cpp b/src/core/net/ip6.cpp index 027e8f24c..7a6e0f1b7 100644 --- a/src/core/net/ip6.cpp +++ b/src/core/net/ip6.cpp @@ -1102,6 +1102,15 @@ Error Ip6::SendRaw(OwnedPtr aMessagePtr) ExitNow(error = kErrorDrop); } + // When the message is forwarded from host to Thread, drop it if + // its source is a link-local address that does not belong to the + // Thread interface. + if (header.GetSource().IsLinkLocalUnicast() && !Get().HasUnicastAddress(header.GetSource())) + { + LogInfo("Dropping packet with foreign link-local source address"); + ExitNow(error = kErrorDrop); + } + // When the packet is forwarded from host to Thread, if its source is on-mesh or its destination is // mesh-local, we'll drop the packet unless the packet originates from this device. if (Get().IsOnMesh(header.GetSource()) || diff --git a/tests/nexus/platform/nexus_infra_if.cpp b/tests/nexus/platform/nexus_infra_if.cpp index 413ffe67d..4779923b8 100644 --- a/tests/nexus/platform/nexus_infra_if.cpp +++ b/tests/nexus/platform/nexus_infra_if.cpp @@ -97,14 +97,19 @@ void InfraIf::RemoveAllAddresses(void) const Ip6::Address *InfraIf::FindAddress(const char *aPrefix) const { - Ip6::Prefix prefix; - const Ip6::Address *matchedAddress = nullptr; + Ip6::Prefix prefix; SuccessOrQuit(prefix.FromString(aPrefix)); + return FindAddress(prefix); +} + +const Ip6::Address *InfraIf::FindAddress(const Ip6::Prefix &aPrefix) const +{ + const Ip6::Address *matchedAddress = nullptr; for (const Ip6::Address &address : mAddresses) { - if (address.MatchesPrefix(prefix)) + if (address.MatchesPrefix(aPrefix)) { matchedAddress = &address; break; diff --git a/tests/nexus/platform/nexus_infra_if.hpp b/tests/nexus/platform/nexus_infra_if.hpp index 1b143ea63..15b533b53 100644 --- a/tests/nexus/platform/nexus_infra_if.hpp +++ b/tests/nexus/platform/nexus_infra_if.hpp @@ -53,6 +53,7 @@ public: void RemoveAllAddresses(void); const Ip6::Address *FindAddress(const char *aPrefix) const; + const Ip6::Address *FindAddress(const Ip6::Prefix &aPrefix) const; const Ip6::Address &FindMatchingAddress(const char *aPrefix) const; const Ip6::Address &GetLinkLocalAddress(void) const { return mAddresses[0]; } diff --git a/tests/nexus/test_1_2_MATN_TC_21.cpp b/tests/nexus/test_1_2_MATN_TC_21.cpp index faae49957..0e4a18a92 100644 --- a/tests/nexus/test_1_2_MATN_TC_21.cpp +++ b/tests/nexus/test_1_2_MATN_TC_21.cpp @@ -149,6 +149,7 @@ void TestMatnTc21(void) Ip6::Address mae1; Ip6::Address mae2; Ip6::Address mae3; + Ip6::Prefix onLinkPrefix; br1.SetName("BR_1"); br2.SetName("BR_2"); @@ -206,6 +207,8 @@ void TestMatnTc21(void) VerifyOrQuit(br1.Get().IsPrimary()); VerifyOrQuit(!br2.Get().IsPrimary()); + SuccessOrQuit(br1.Get().GetFavoredOnLinkPrefix(onLinkPrefix)); + nexus.AddTestVar("MA1", kMA1); nexus.AddTestVar("MA3", kMA3); nexus.AddTestVar("MA5", kMA5); @@ -410,8 +413,14 @@ void TestMatnTc21(void) * - N/A */ Log("Step 16: Host sends a ICMPv6 Echo Request to MA1 on the backbone link."); - host.mInfraIf.SendEchoRequest(host.mInfraIf.GetLinkLocalAddress(), ma1, kEchoIdentifier, kEchoPayloadSize); - nexus.AdvanceTime(0); + { + const Ip6::Address *srcAddr; + + srcAddr = host.mInfraIf.FindAddress(onLinkPrefix); + VerifyOrQuit(srcAddr != nullptr); + host.mInfraIf.SendEchoRequest(*srcAddr, ma1, kEchoIdentifier, kEchoPayloadSize); + nexus.AdvanceTime(0); + } /** * Step 17 diff --git a/tests/nexus/verify_1_3_DBR_TC_1.py b/tests/nexus/verify_1_3_DBR_TC_1.py index 0228dd6d5..8bb71754c 100644 --- a/tests/nexus/verify_1_3_DBR_TC_1.py +++ b/tests/nexus/verify_1_3_DBR_TC_1.py @@ -301,7 +301,6 @@ def verify(pv): pkts.filter_wpan_src64(BR_1).\ filter_ipv6_src(Ipv6Addr(pv.vars['ETH_1_LL_ADDR'])).\ - filter_ipv6_dst(ED_1_OMR).\ filter_ping_request().\ must_not_next()