[icmp] add `OT_ICMP6_ECHO_HANDLER_RLOC_ALOC_ONLY` to `otIcmp6EchoMode` (#10014)

When an icmp echo request is sent to rloc/aloc address of a Thread
device, OT replies to the packet. The packet is also passed to host
and the kernel may reply to the echo request. This would cause 2 echo
replies and may be confusing when testing packet loss rate by pinging
a rloc/aloc address.

Added OT_ICMP6_ECHO_HANDLER_RLOC_ALOC_ONLY to otIcmp6EchoMode to let
OT only handle echo request to rloc/aloc addresses, this is the
default mode in posix code. Set otIcmp6EchoMode to
OT_ICMP6_ECHO_HANDLER_DISABLED will help to avoid double ping replies
from both OT and host.

(cherry picked from commit 59572efb4e51c9b0218e840bad8c6dc7758dc3a0)

Bug: 333493455

Change-Id: If6cfdf187310d41d633199274b93d0f5c6488871
diff --git a/include/openthread/icmp6.h b/include/openthread/icmp6.h
index 32f8c6a..925871c 100644
--- a/include/openthread/icmp6.h
+++ b/include/openthread/icmp6.h
@@ -144,6 +144,7 @@
     OT_ICMP6_ECHO_HANDLER_UNICAST_ONLY   = 1, ///< ICMPv6 Echo processing enabled only for unicast requests only
     OT_ICMP6_ECHO_HANDLER_MULTICAST_ONLY = 2, ///< ICMPv6 Echo processing enabled only for multicast requests only
     OT_ICMP6_ECHO_HANDLER_ALL            = 3, ///< ICMPv6 Echo processing enabled for unicast and multicast requests
+    OT_ICMP6_ECHO_HANDLER_RLOC_ALOC_ONLY = 4, ///< ICMPv6 Echo processing enabled for RLOC/ALOC destinations only
 } otIcmp6EchoMode;
 
 /**
diff --git a/include/openthread/instance.h b/include/openthread/instance.h
index 1ce766c..a956397 100644
--- a/include/openthread/instance.h
+++ b/include/openthread/instance.h
@@ -53,7 +53,7 @@
  * @note This number versions both OpenThread platform and user APIs.
  *
  */
-#define OPENTHREAD_API_VERSION (402)
+#define OPENTHREAD_API_VERSION (405)
 
 /**
  * @addtogroup api-instance
diff --git a/src/core/net/icmp6.cpp b/src/core/net/icmp6.cpp
index 5bcea06..3dba7ca 100644
--- a/src/core/net/icmp6.cpp
+++ b/src/core/net/icmp6.cpp
@@ -171,6 +171,9 @@
     case OT_ICMP6_ECHO_HANDLER_ALL:
         rval = true;
         break;
+    case OT_ICMP6_ECHO_HANDLER_RLOC_ALOC_ONLY:
+        rval = aMessageInfo.GetSockAddr().GetIid().IsLocator();
+        break;
     }
 
     return rval;
@@ -184,8 +187,7 @@
     MessageInfo replyMessageInfo;
     uint16_t    dataOffset;
 
-    // always handle Echo Request destined for RLOC or ALOC
-    VerifyOrExit(ShouldHandleEchoRequest(aMessageInfo) || aMessageInfo.GetSockAddr().GetIid().IsLocator());
+    VerifyOrExit(ShouldHandleEchoRequest(aMessageInfo));
 
     LogInfo("Received Echo Request");
 
diff --git a/src/lib/spinel/spinel.h b/src/lib/spinel/spinel.h
index d91a039..c1865f3 100644
--- a/src/lib/spinel/spinel.h
+++ b/src/lib/spinel/spinel.h
@@ -607,6 +607,7 @@
     SPINEL_IPV6_ICMP_PING_OFFLOAD_UNICAST_ONLY   = 1,
     SPINEL_IPV6_ICMP_PING_OFFLOAD_MULTICAST_ONLY = 2,
     SPINEL_IPV6_ICMP_PING_OFFLOAD_ALL            = 3,
+    SPINEL_IPV6_ICMP_PING_OFFLOAD_RLOC_ALOC_ONLY = 4,
 } spinel_ipv6_icmp_ping_offload_mode_t;
 
 typedef enum
@@ -3457,6 +3458,7 @@
      *   SPINEL_IPV6_ICMP_PING_OFFLOAD_UNICAST_ONLY   = 1
      *   SPINEL_IPV6_ICMP_PING_OFFLOAD_MULTICAST_ONLY = 2
      *   SPINEL_IPV6_ICMP_PING_OFFLOAD_ALL            = 3
+     *   SPINEL_IPV6_ICMP_PING_OFFLOAD_RLOC_ALOC_ONLY = 4
      *
      * Default value is `NET_IPV6_ICMP_PING_OFFLOAD_DISABLED`.
      *
diff --git a/src/ncp/ncp_base.cpp b/src/ncp/ncp_base.cpp
index a1ad3ad..96e3625 100644
--- a/src/ncp/ncp_base.cpp
+++ b/src/ncp/ncp_base.cpp
@@ -340,7 +340,7 @@
 #if OPENTHREAD_CONFIG_UDP_FORWARD_ENABLE
     otUdpForwardSetForwarder(mInstance, &NcpBase::HandleUdpForwardStream, this);
 #endif
-    otIcmp6SetEchoMode(mInstance, OT_ICMP6_ECHO_HANDLER_DISABLED);
+    otIcmp6SetEchoMode(mInstance, OT_ICMP6_ECHO_HANDLER_RLOC_ALOC_ONLY);
 #if OPENTHREAD_FTD
     otThreadRegisterNeighborTableCallback(mInstance, &NcpBase::HandleNeighborTableChanged);
 #if OPENTHREAD_CONFIG_MLE_STEERING_DATA_SET_OOB_ENABLE
diff --git a/src/ncp/ncp_base_mtd.cpp b/src/ncp/ncp_base_mtd.cpp
index aa87efa..227ce61 100644
--- a/src/ncp/ncp_base_mtd.cpp
+++ b/src/ncp/ncp_base_mtd.cpp
@@ -2072,6 +2072,9 @@
     case OT_ICMP6_ECHO_HANDLER_ALL:
         mode = SPINEL_IPV6_ICMP_PING_OFFLOAD_ALL;
         break;
+    case OT_ICMP6_ECHO_HANDLER_RLOC_ALOC_ONLY:
+        mode = SPINEL_IPV6_ICMP_PING_OFFLOAD_RLOC_ALOC_ONLY;
+        break;
     };
 
     return mEncoder.WriteUint8(mode);
@@ -2099,6 +2102,9 @@
     case SPINEL_IPV6_ICMP_PING_OFFLOAD_ALL:
         mode = OT_ICMP6_ECHO_HANDLER_ALL;
         break;
+    case SPINEL_IPV6_ICMP_PING_OFFLOAD_RLOC_ALOC_ONLY:
+        mode = OT_ICMP6_ECHO_HANDLER_RLOC_ALOC_ONLY;
+        break;
     };
 
     otIcmp6SetEchoMode(mInstance, mode);