[ncp] extend border routing InfraIf setup for state synchronization (#10749)

The commit extends `SPINEL_PROP_INFRA_IF_SETUP` to
`SPINEL_PROP_INFRA_IF_STATE` so that it can be used to either do infra
if setup (trigger border routing starting on NCP) or synchronize infra
if state to the NCP (ON/OFF state, IP addresses).

The current implementation on NCP will compare the `InfraIfIndex`. If
the index is different the value on NCP, it will be regarded as an
initialization or change of InfraIf. Thus the border routing module
will be re-initialized.
This commit is contained in:
Li Cao
2024-09-25 08:18:16 -07:00
committed by GitHub
parent af2c77e171
commit 2388bc2264
4 changed files with 66 additions and 15 deletions
+8 -3
View File
@@ -4729,15 +4729,20 @@ enum
SPINEL_PROP_INFRA_IF__BEGIN = 0x910,
/// Infrastructure interface setup.
/// Infrastructure interface state.
/** Format: `LbA(6)`
* Type: Write
*
* `L`: The infrastructure interface index.
* `b`: If the infrastrue interface is running.
* `b`: If the infrastructure interface is running.
* `A(6)`: The IPv6 addresses of the infrastructure interface.
*
* If the InfraIf hasn't been set up on NCP or the InfraIf changes, NCP will re-initialize
* the border routing module. NCP will compare the infrastructure interface index and decide
* whether to re-initialize the border routing module. Otherwise, NCP will simply update the
* InfraIf state and addresses.
*/
SPINEL_PROP_INFRA_IF_SETUP = SPINEL_PROP_INFRA_IF__BEGIN + 1,
SPINEL_PROP_INFRA_IF_STATE = SPINEL_PROP_INFRA_IF__BEGIN + 1,
SPINEL_PROP_INFRA_IF__END = 0x920,
+1 -1
View File
@@ -513,7 +513,7 @@ NcpBase::PropertyHandler NcpBase::FindSetPropertyHandler(spinel_prop_key_t aKey)
OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_MULTIPAN_ACTIVE_INTERFACE),
#endif
#if OPENTHREAD_FTD && OPENTHREAD_CONFIG_NCP_INFRA_IF_ENABLE
OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_INFRA_IF_SETUP),
OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_INFRA_IF_STATE),
#endif
#if OPENTHREAD_MTD || OPENTHREAD_FTD
OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_UNSOL_UPDATE_FILTER),
+16 -7
View File
@@ -1404,12 +1404,13 @@ exit:
#endif // OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
#if OPENTHREAD_CONFIG_NCP_INFRA_IF_ENABLE
template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_INFRA_IF_SETUP>(void)
template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_INFRA_IF_STATE>(void)
{
otError error = OT_ERROR_NONE;
bool isInfraRunning;
otError error = OT_ERROR_NONE;
uint32_t infraIfIndex;
bool isInfraRunning;
SuccessOrExit(error = mDecoder.ReadUint32(mInfraIfIndex));
SuccessOrExit(error = mDecoder.ReadUint32(infraIfIndex));
SuccessOrExit(error = mDecoder.ReadBool(isInfraRunning));
mInfraIfAddrCount = 0;
@@ -1421,9 +1422,17 @@ template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_INFRA_IF_SETUP>(void)
SuccessOrExit(error = InfraIfAddAddress(*addr));
}
IgnoreError(otBorderRoutingSetEnabled(mInstance, /* aEnabled */ false));
SuccessOrExit(error = otBorderRoutingInit(mInstance, mInfraIfIndex, isInfraRunning));
SuccessOrExit(error = otBorderRoutingSetEnabled(mInstance, /* aEnabled */ true));
if (infraIfIndex != mInfraIfIndex)
{
mInfraIfIndex = infraIfIndex;
IgnoreError(otBorderRoutingSetEnabled(mInstance, /* aEnabled */ false));
SuccessOrExit(error = otBorderRoutingInit(mInstance, mInfraIfIndex, isInfraRunning));
SuccessOrExit(error = otBorderRoutingSetEnabled(mInstance, /* aEnabled */ true));
}
else
{
SuccessOrExit(error = otPlatInfraIfStateChanged(mInstance, mInfraIfIndex, isInfraRunning));
}
exit:
return error;
+41 -4
View File
@@ -44,7 +44,7 @@ namespace ot {
constexpr uint16_t kMaxSpinelBufferSize = 2048;
static otError GenerateSpinelInfraIfSetUpFrame(uint32_t akInfraIfIndex,
static otError GenerateSpinelInfraIfStateFrame(uint32_t akInfraIfIndex,
bool aIsRunning,
const otIp6Address *aAddrs,
uint8_t aAddrCount,
@@ -57,7 +57,7 @@ static otError GenerateSpinelInfraIfSetUpFrame(uint32_t akInfraIfInde
Spinel::Encoder encoder(ncpBuffer);
uint8_t header = SPINEL_HEADER_FLAG | 0 /* Iid */ | 1 /* Tid */;
SuccessOrExit(error = encoder.BeginFrame(header, SPINEL_CMD_PROP_VALUE_SET, SPINEL_PROP_INFRA_IF_SETUP));
SuccessOrExit(error = encoder.BeginFrame(header, SPINEL_CMD_PROP_VALUE_SET, SPINEL_PROP_INFRA_IF_STATE));
SuccessOrExit(error = encoder.WriteUint32(akInfraIfIndex));
SuccessOrExit(error = encoder.WriteBool(true));
for (uint8_t i = 0; i < aAddrCount; i++)
@@ -89,7 +89,7 @@ void TestNcpInfraIfSetUp(void)
VerifyOrQuit(otBorderRoutingGetState(instance) == OT_BORDER_ROUTING_STATE_UNINITIALIZED);
SuccessOrQuit(GenerateSpinelInfraIfSetUpFrame(kInfraIfIndex, true /* IsRunning */, infraIfAddresses,
SuccessOrQuit(GenerateSpinelInfraIfStateFrame(kInfraIfIndex, true /* IsRunning */, infraIfAddresses,
sizeof(infraIfAddresses) / sizeof(infraIfAddresses[0]), recvBuf,
recvLen));
ncpBase.HandleReceive(recvBuf, recvLen);
@@ -98,7 +98,7 @@ void TestNcpInfraIfSetUp(void)
VerifyOrQuit(!otPlatInfraIfHasAddress(kInfraIfIndex + 100, &infraIfAddresses[0]));
SuccessOrQuit(
GenerateSpinelInfraIfSetUpFrame(kInfraIfIndex, true /* IsRunning */, infraIfAddresses, 0, recvBuf, recvLen));
GenerateSpinelInfraIfStateFrame(kInfraIfIndex, true /* IsRunning */, infraIfAddresses, 0, recvBuf, recvLen));
ncpBase.HandleReceive(recvBuf, recvLen);
VerifyOrQuit(otBorderRoutingGetState(instance) == OT_BORDER_ROUTING_STATE_STOPPED);
VerifyOrQuit(!otPlatInfraIfHasAddress(kInfraIfIndex, &infraIfAddresses[0]));
@@ -106,6 +106,42 @@ void TestNcpInfraIfSetUp(void)
printf("Test Ncp Infra If SetUp passed.\n");
}
void TestNcpInfraIfUpdate(void)
{
Instance *instance = static_cast<Instance *>(testInitInstance());
Ncp::NcpBase ncpBase(instance);
uint8_t recvBuf[kMaxSpinelBufferSize];
uint16_t recvLen;
constexpr uint32_t kInfraIfIndex1 = 1;
constexpr uint32_t kInfraIfIndex2 = 2;
const otIp6Address infraIfAddresses[] = {
{0xfd, 0x35, 0x7a, 0x7d, 0x0f, 0x16, 0xe7, 0xe3, 0xc9, 0x79, 0x59, 0x29, 0xc8, 0xc2, 0xa3, 0x7b},
{0xfd, 0x35, 0x7a, 0x7d, 0x0f, 0x16, 0xe7, 0xe3, 0x7b, 0xa3, 0xc2, 0xc8, 0x29, 0x59, 0x79, 0xc9},
};
SuccessOrQuit(
GenerateSpinelInfraIfStateFrame(kInfraIfIndex1, true /* IsRunning */, infraIfAddresses, 1, recvBuf, recvLen));
ncpBase.HandleReceive(recvBuf, recvLen);
VerifyOrQuit(otPlatInfraIfHasAddress(kInfraIfIndex1, &infraIfAddresses[0]));
VerifyOrQuit(!otPlatInfraIfHasAddress(kInfraIfIndex1, &infraIfAddresses[1]));
SuccessOrQuit(
GenerateSpinelInfraIfStateFrame(kInfraIfIndex1, true /* IsRunning */, infraIfAddresses, 2, recvBuf, recvLen));
ncpBase.HandleReceive(recvBuf, recvLen);
VerifyOrQuit(otPlatInfraIfHasAddress(kInfraIfIndex1, &infraIfAddresses[0]));
VerifyOrQuit(otPlatInfraIfHasAddress(kInfraIfIndex1, &infraIfAddresses[1]));
SuccessOrQuit(
GenerateSpinelInfraIfStateFrame(kInfraIfIndex2, true /* IsRunning */, infraIfAddresses, 2, recvBuf, recvLen));
ncpBase.HandleReceive(recvBuf, recvLen);
VerifyOrQuit(!otPlatInfraIfHasAddress(kInfraIfIndex1, &infraIfAddresses[0]));
VerifyOrQuit(!otPlatInfraIfHasAddress(kInfraIfIndex1, &infraIfAddresses[1]));
VerifyOrQuit(otPlatInfraIfHasAddress(kInfraIfIndex2, &infraIfAddresses[0]));
VerifyOrQuit(otPlatInfraIfHasAddress(kInfraIfIndex2, &infraIfAddresses[1]));
}
} // namespace ot
#endif // OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE && OPENTHREAD_CONFIG_NCP_INFRA_IF_ENABLE
@@ -114,6 +150,7 @@ int main(void)
{
#if OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE && OPENTHREAD_CONFIG_NCP_INFRA_IF_ENABLE
ot::TestNcpInfraIfSetUp();
ot::TestNcpInfraIfUpdate();
#endif
printf("All tests passed\n");
return 0;