diff --git a/include/openthread/instance.h b/include/openthread/instance.h index eee33cf59..b67b303f1 100644 --- a/include/openthread/instance.h +++ b/include/openthread/instance.h @@ -53,7 +53,7 @@ extern "C" { * @note This number versions both OpenThread platform and user APIs. * */ -#define OPENTHREAD_API_VERSION (378) +#define OPENTHREAD_API_VERSION (379) /** * @addtogroup api-instance diff --git a/include/openthread/srp_client.h b/include/openthread/srp_client.h index 6eac2b1a8..71a217c37 100644 --- a/include/openthread/srp_client.h +++ b/include/openthread/srp_client.h @@ -460,10 +460,10 @@ otError otSrpClientSetHostName(otInstance *aInstance, const char *aName); /** * Enables auto host address mode. * - * When enabled host IPv6 addresses are automatically set by SRP client using all the unicast addresses on Thread netif - * excluding all link-local and mesh-local addresses. If there is no valid address, then Mesh Local EID address is - * added. The SRP client will automatically re-register when/if addresses on Thread netif are updated (new addresses - * are added or existing addresses are removed). + * When enabled host IPv6 addresses are automatically set by SRP client using all the preferred unicast addresses on + * Thread netif excluding all link-local and mesh-local addresses. If there is no preferred address, then Mesh Local + * EID address is added. The SRP client will automatically re-register when/if addresses on Thread netif are updated + * (new addresses are added or existing addresses are removed or marked as non-preferred). * * The auto host address mode can be enabled before start or during operation of SRP client except when the host info * is being removed (client is busy handling a remove request from an call to `otSrpClientRemoveHostAndServices()` and diff --git a/src/cli/README_SRP_CLIENT.md b/src/cli/README_SRP_CLIENT.md index ae48fbf1e..ca486f310 100644 --- a/src/cli/README_SRP_CLIENT.md +++ b/src/cli/README_SRP_CLIENT.md @@ -187,7 +187,7 @@ fd00:0:0:0:0:0:0:beef Done ``` -Enable auto host address mode. When enabled client will automatically use all Thread netif unicast addresses excluding all link-local and mesh-local addresses. If there is no valid address, then Mesh Local EID address is added. SRP client will automatically re-register if/when addresses on Thread netif get changed (e.g., new address is added or existing address is removed). +Enable auto host address mode. When enabled client will automatically use all preferred Thread netif unicast addresses excluding all link-local and mesh-local addresses. If there is no preferred address, then Mesh Local EID address is added. SRP client will automatically re-register if/when addresses on Thread netif get changed (e.g., new address is added or existing address is removed or marked as non-preferred). ```bash > srp client host address auto diff --git a/src/cli/cli_srp_client.cpp b/src/cli/cli_srp_client.cpp index e32903258..58c9ef457 100644 --- a/src/cli/cli_srp_client.cpp +++ b/src/cli/cli_srp_client.cpp @@ -315,12 +315,12 @@ template <> otError SrpClient::Process(Arg aArgs[]) * @endcode * @cparam srp client host address [auto|@ca{address...}] * * Use the `auto` parameter to enable auto host address mode. - * When enabled, the client automatically uses all Thread `netif` - * unicast addresses except for link-local and mesh-local + * When enabled, the client automatically uses all preferred Thread + * `netif` unicast addresses except for link-local and mesh-local * addresses. If there is no valid address, the mesh local * EID address gets added. The SRP client automatically * re-registers if addresses on the Thread `netif` are - * added or removed. + * added or removed or marked as non-preferred. * * Explicitly specify the list of host addresses, separating * each address by a space. You can set this list while the client is * running. This will also disable auto host address mode. diff --git a/src/core/net/srp_client.cpp b/src/core/net/srp_client.cpp index 9663d9299..617091ca1 100644 --- a/src/core/net/srp_client.cpp +++ b/src/core/net/srp_client.cpp @@ -1240,21 +1240,23 @@ Error Client::AppendHostDescriptionInstruction(Message &aMessage, Info &aInfo) if (mHostInfo.IsAutoAddressEnabled()) { - // Append all addresses on Thread netif excluding link-local and - // mesh-local addresses. If no address is appended, we include - // the mesh local address. + // Append all preferred addresses on Thread netif excluding link-local + // and mesh-local addresses. If no address is appended, we include + // the mesh local EID. mAutoHostAddressAddedMeshLocal = true; for (const Ip6::Netif::UnicastAddress &unicastAddress : Get().GetUnicastAddresses()) { - if (unicastAddress.GetAddress().IsLinkLocal() || - Get().IsMeshLocalAddress(unicastAddress.GetAddress())) + const Ip6::Address &address = unicastAddress.GetAddress(); + + if (address.IsLinkLocal() || Get().IsMeshLocalAddress(address) || !unicastAddress.mPreferred || + !unicastAddress.mValid) { continue; } - SuccessOrExit(error = AppendAaaaRecord(unicastAddress.GetAddress(), aMessage, aInfo)); + SuccessOrExit(error = AppendAaaaRecord(address, aMessage, aInfo)); mAutoHostAddressAddedMeshLocal = false; } diff --git a/tests/scripts/thread-cert/node.py b/tests/scripts/thread-cert/node.py index aa8416f21..25e254aba 100755 --- a/tests/scripts/thread-cert/node.py +++ b/tests/scripts/thread-cert/node.py @@ -1880,8 +1880,8 @@ class NodeImpl: self.send_command(cmd) self._expect_done() - def get_addrs(self): - self.send_command('ipaddr') + def get_addrs(self, verbose=False): + self.send_command('ipaddr' + (' -v' if verbose else '')) return self._expect_results(r'\S+(:\S*)+') diff --git a/tests/scripts/thread-cert/test_srp_auto_host_address.py b/tests/scripts/thread-cert/test_srp_auto_host_address.py index bb9ac6e1e..f714e6c4a 100755 --- a/tests/scripts/thread-cert/test_srp_auto_host_address.py +++ b/tests/scripts/thread-cert/test_srp_auto_host_address.py @@ -155,6 +155,19 @@ class SrpAutoHostAddress(thread_cert.TestCase): self.assertEqual(len(slaac_addr), 1) self.check_registered_addresses(client, server) + #------------------------------------------------------------------- + # Add a non-preferred SLAAC on-mesh prefix and check that the + # set of registered addresses remains unchanged and that the + # non-preferred address is not registered by SRP client. + + client.add_prefix('fd00:a:b:c::/64', 'aos') + client.register_netdata() + self.simulator.go(5) + + slaac_addr = [addr.strip() for addr in client.get_addrs() if addr.strip().startswith('fd00:a:b:c:')] + self.assertEqual(len(slaac_addr), 1) + self.check_registered_addresses(client, server) + #------------------------------------------------------------------- # Remove the on-mesh prefix (which will trigger an address to be # removed) and check that the SRP client re-registered and updated @@ -219,19 +232,21 @@ class SrpAutoHostAddress(thread_cert.TestCase): # Check the host addresses on server to match client. host_addresses = [addr.strip() for addr in server_host['addresses']] - client_addresses = [addr.strip() for addr in client.get_addrs()] + + client_mleid = client.get_mleid() + client_addresses = [addr.split(' ')[0] for addr in client.get_addrs(verbose=True) if 'preferred:1' in addr] + client_addresses += [client_mleid] # All registered addresses must be in client list of addresses. for addr in host_addresses: self.assertIn(addr, client_addresses) - # All addresses on client excluding link-local and mesh-local - # addresses must be seen on server side. But if there was - # no address, then mesh-local address should be the only + # All preferred addresses on client excluding link-local and + # mesh-local addresses must be seen on server side. But if there + # was no address, then mesh-local address should be the only # one registered. - client_mleid = client.get_mleid() checked_address = False for addr in client_addresses: