Skip to content
This repository was archived by the owner on Dec 20, 2023. It is now read-only.

Commit c78478e

Browse files
committed
Fix re-joining to the disconnected Thread network
When the OpenThread interface is disconnected, the Thread stack removes the addresses on that interface. By the time WARM has a chance to deal with the situation, the Weave ULA address is no longer on the interface, and the LwIP call `netif_remove_ip6_address_with_route` returns an error code. In turn, when WARM observes that the operation to remove the address fails, it does not update the state accordingly. When the device rejoins, WARM (having failed to update the state), does not reassign the Weave ULA address to the interface. As a result, all the packets going out to Weave addresses (and the service address in particular) are sent with the Thread mesh-local address as the source address and thus fail to be routed properly. By squashing the error on remove, we enable the WARM state machine to re-add the Weave ULA address on reattach, and thus put all routing decisions back on their well-worn paths. We adopt the same approach to handle the internal address on the OpenThread netif.
1 parent 71f49e3 commit c78478e

File tree

1 file changed

+19
-1
lines changed

1 file changed

+19
-1
lines changed

src/adaptations/device-layer/LwIP/WarmSupport.cpp

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,15 @@ PlatformResult AddRemoveHostAddress(InterfaceType inInterfaceType, const Inet::I
132132
else
133133
{
134134
lwipErr = netif_remove_ip6_address_with_route(netif, &ip6addr, inPrefixLength);
135+
// There are two possible errors from netif_remove_ip6_address: ERR_ARG
136+
// if call was made with wrong arguments, or ERR_VAL if the action could
137+
// not be performed (e.g. the address was already removed). We squash
138+
// ERR_VAL, and return SUCCESS so that WARM can set its state correctly.
139+
if (lwipErr == ERR_VAL)
140+
{
141+
WeaveLogProgress(DeviceLayer, "netif_remove_ip6_address_with_route: Already removed");
142+
lwipErr = ERR_OK;
143+
}
135144
err = System::MapErrorLwIP(lwipErr);
136145
if (err != WEAVE_NO_ERROR)
137146
{
@@ -311,6 +320,16 @@ PlatformResult AddRemoveThreadAddress(InterfaceType inInterfaceType, const Inet:
311320
else
312321
{
313322
otErr = otIp6RemoveUnicastAddress(ThreadStackMgrImpl().OTInstance(), &otAddress.mAddress);
323+
// There are two possible errors from otIp6RemoveUnicastAddress:
324+
// OT_ERROR_INVALID_ARGS if the address was a multicast address, and
325+
// OT_ERROR_NOT_FOUND if the address does not exist on the thread
326+
// interface. We squash the OT_ERROR_NOT_FOUND so that WARM sets its
327+
// state correctly.
328+
if (otErr == OT_ERROR_NOT_FOUND)
329+
{
330+
WeaveLogProgress(DeviceLayer, "otIp6RemoveUnicastAddress: already removed");
331+
otErr = OT_ERROR_NONE;
332+
}
314333
}
315334

316335
ThreadStackMgrImpl().UnlockThreadStack();
@@ -442,4 +461,3 @@ const char * WarmInterfaceTypeToStr(InterfaceType inInterfaceType)
442461
} // namespace DeviceLayer
443462
} // namespace Weave
444463
} // namespace nl
445-

0 commit comments

Comments
 (0)