[slaac] set plen to 128 if prefix is not on-mesh (#5116)
diff --git a/src/core/utils/slaac_address.cpp b/src/core/utils/slaac_address.cpp
index 101b480..f4d6468 100644
--- a/src/core/utils/slaac_address.cpp
+++ b/src/core/utils/slaac_address.cpp
@@ -138,6 +138,14 @@
     return;
 }
 
+bool Slaac::DoesConfigMatchNetifAddr(const NetworkData::OnMeshPrefixConfig &aConfig,
+                                     const Ip6::NetifUnicastAddress &       aAddr)
+{
+    return (((aConfig.mOnMesh && (aAddr.mPrefixLength == aConfig.mPrefix.mLength)) ||
+             (!aConfig.mOnMesh && (aAddr.mPrefixLength == 128))) &&
+            (aAddr.GetAddress().PrefixMatch(aConfig.mPrefix.mPrefix) >= aConfig.mPrefix.mLength));
+}
+
 void Slaac::Update(UpdateMode aMode)
 {
     NetworkData::Iterator           iterator;
@@ -165,16 +173,13 @@
 
                 while (Get<NetworkData::Leader>().GetNextOnMeshPrefix(iterator, config) == OT_ERROR_NONE)
                 {
-                    otIp6Prefix &prefix = config.mPrefix;
-
                     if (config.mDp)
                     {
                         // Skip domain prefix which is processed in MLE.
                         continue;
                     }
 
-                    if (config.mSlaac && !ShouldFilter(prefix) && (prefix.mLength == slaacAddr->mPrefixLength) &&
-                        (slaacAddr->GetAddress().PrefixMatch(prefix.mPrefix) >= prefix.mLength))
+                    if (config.mSlaac && !ShouldFilter(config.mPrefix) && DoesConfigMatchNetifAddr(config, *slaacAddr))
                     {
                         found = true;
                         break;
@@ -212,8 +217,7 @@
             for (const Ip6::NetifUnicastAddress *netifAddr = Get<ThreadNetif>().GetUnicastAddresses();
                  netifAddr != nullptr; netifAddr           = netifAddr->GetNext())
             {
-                if ((netifAddr->mPrefixLength == prefix.mLength) &&
-                    (netifAddr->GetAddress().PrefixMatch(prefix.mPrefix) >= prefix.mLength))
+                if (DoesConfigMatchNetifAddr(config, *netifAddr))
                 {
                     found = true;
                     break;
@@ -234,7 +238,7 @@
                     slaacAddr->Clear();
                     memcpy(&slaacAddr->mAddress, &prefix.mPrefix, BitVectorBytes(prefix.mLength));
 
-                    slaacAddr->mPrefixLength  = prefix.mLength;
+                    slaacAddr->mPrefixLength  = config.mOnMesh ? prefix.mLength : 128;
                     slaacAddr->mAddressOrigin = OT_ADDRESS_ORIGIN_SLAAC;
                     slaacAddr->mPreferred     = config.mPreferred;
                     slaacAddr->mValid         = true;
diff --git a/src/core/utils/slaac_address.hpp b/src/core/utils/slaac_address.hpp
index b391d47..3c035ce 100644
--- a/src/core/utils/slaac_address.hpp
+++ b/src/core/utils/slaac_address.hpp
@@ -39,6 +39,7 @@
 #include "common/locator.hpp"
 #include "common/notifier.hpp"
 #include "net/netif.hpp"
+#include "thread/network_data.hpp"
 
 namespace ot {
 namespace Utils {
@@ -163,6 +164,8 @@
     void        GetIidSecretKey(IidSecretKey &aKey) const;
     static void HandleNotifierEvents(Notifier::Receiver &aReceiver, Events aEvents);
     void        HandleNotifierEvents(Events aEvents);
+    static bool DoesConfigMatchNetifAddr(const NetworkData::OnMeshPrefixConfig &aConfig,
+                                         const Ip6::NetifUnicastAddress &       aAddr);
 
     bool                     mEnabled;
     otIp6SlaacPrefixFilter   mFilter;