mirror of
https://github.com/espressif/openthread.git
synced 2026-07-28 22:57:47 +00:00
[netdata] add otNetDataReplacePublishedExternalRoute() API (#9013)
This commit adds a public OT API to replace a previously published external route entry in the Thread Network Data. It also adds a related CLI command, and updates `test_netdata_publisher` to validate the new behavior.
This commit is contained in:
@@ -53,7 +53,7 @@ extern "C" {
|
||||
* @note This number versions both OpenThread platform and user APIs.
|
||||
*
|
||||
*/
|
||||
#define OPENTHREAD_API_VERSION (318)
|
||||
#define OPENTHREAD_API_VERSION (319)
|
||||
|
||||
/**
|
||||
* @addtogroup api-instance
|
||||
|
||||
@@ -237,6 +237,42 @@ otError otNetDataPublishOnMeshPrefix(otInstance *aInstance, const otBorderRouter
|
||||
*/
|
||||
otError otNetDataPublishExternalRoute(otInstance *aInstance, const otExternalRouteConfig *aConfig);
|
||||
|
||||
/**
|
||||
* This function replaces a previously published external route in the Thread Network Data.
|
||||
*
|
||||
* This function requires the feature `OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE` to be enabled.
|
||||
*
|
||||
* If there is no previously published external route matching @p aPrefix, this function behaves similarly to
|
||||
* `otNetDataPublishExternalRoute()`, i.e., it will start the process of publishing @a aConfig as an external route in
|
||||
* the Thread Network Data.
|
||||
*
|
||||
* If there is a previously published route entry matching @p aPrefix, it will be replaced with the new prefix from
|
||||
* @p aConfig.
|
||||
*
|
||||
* - If the @p aPrefix was already added in the Network Data, the change to the new prefix in @p aConfig is immediately
|
||||
* reflected in the Network Data. This ensures that route entries in the Network Data are not abruptly removed and
|
||||
* the transition from aPrefix to the new prefix is smooth.
|
||||
*
|
||||
* - If the old published @p aPrefix was not added in the Network Data, it will be replaced with the new @p aConfig
|
||||
* prefix but it will not be immediately added. Instead, it will start the process of publishing it in the Network
|
||||
* Data (monitoring the Network Data to determine when/if to add the prefix, depending on the number of similar
|
||||
* prefixes present in the Network Data).
|
||||
*
|
||||
* @param[in] aPrefix The previously published external route prefix to replace.
|
||||
* @param[in] aConfig The external route config to publish.
|
||||
* @param[in] aRequester The requester (`kFromUser` or `kFromRoutingManager` module).
|
||||
*
|
||||
* @retval OT_ERROR_NONE The external route is published successfully.
|
||||
* @retval OT_ERROR_INVALID_ARGS The @p aConfig is not valid (bad prefix, invalid flag combinations, or not stable).
|
||||
* @retval OT_ERROR_NO_BUFS Could not allocate an entry for the new request. Publisher supports a limited number
|
||||
* of entries (shared between on-mesh prefix and external route) determined by config
|
||||
* `OPENTHREAD_CONFIG_NETDATA_PUBLISHER_MAX_PREFIX_ENTRIES`.
|
||||
*
|
||||
*/
|
||||
otError otNetDataReplacePublishedExternalRoute(otInstance *aInstance,
|
||||
const otIp6Prefix *aPrefix,
|
||||
const otExternalRouteConfig *aConfig);
|
||||
|
||||
/**
|
||||
* This function indicates whether or not currently a published prefix entry (on-mesh or external route) is added to
|
||||
* the Thread Network Data.
|
||||
|
||||
@@ -269,6 +269,21 @@ Publish an external route entry.
|
||||
Done
|
||||
```
|
||||
|
||||
### publish replace \<old prefix\> \<prefix\> [sn][prf]
|
||||
|
||||
Replace a previously published external route entry.
|
||||
|
||||
If there is no previously published external route matching old prefix, this command behaves similarly to `netdata publish route`. If there is a previously published route entry, it will be replaced with the new prefix. In particular, if the old prefix was already added in the Network Data, the change to the new prefix is immediately reflected in the Network Data (i.e., old prefix is removed and the new prefix is added in the same Network Data registration request to leader). This ensures that route entries in the Network Data are not abruptly removed.
|
||||
|
||||
- s: Stable flag
|
||||
- n: NAT64 flag
|
||||
- prf: Preference, which may be: 'high', 'med', or 'low'.
|
||||
|
||||
```bash
|
||||
> netdata publish replace ::/0 fd00:1234:5678::/64 s high
|
||||
Done
|
||||
```
|
||||
|
||||
### register
|
||||
|
||||
Usage: `netdata register`
|
||||
|
||||
@@ -354,6 +354,29 @@ template <> otError NetworkData::Process<Cmd("publish")>(Arg aArgs[])
|
||||
error = otNetDataPublishExternalRoute(GetInstancePtr(), &config);
|
||||
ExitNow();
|
||||
}
|
||||
|
||||
/**
|
||||
* @cli netdata publish replace
|
||||
* @code
|
||||
* netdata publish replace ::/0 fd00:1234:5678::/64 s high
|
||||
* Done
|
||||
* @endcode
|
||||
* @cparam netdata publish replace @ca{oldprefix} @ca{prefix} [@ca{sn}] [@ca{high}|@ca{med}|@ca{low}]
|
||||
* OT CLI uses mapped arguments to configure #otExternalRouteConfig values. @moreinfo{the @overview}.
|
||||
* @par
|
||||
* Replaces a previously published external route entry. @moreinfo{@netdata}.
|
||||
* @sa otNetDataReplacePublishedExternalRoute
|
||||
*/
|
||||
if (aArgs[0] == "replace")
|
||||
{
|
||||
otIp6Prefix prefix;
|
||||
otExternalRouteConfig config;
|
||||
|
||||
SuccessOrExit(error = aArgs[1].ParseAsIp6Prefix(prefix));
|
||||
SuccessOrExit(error = Interpreter::ParseRoute(aArgs + 2, config));
|
||||
error = otNetDataReplacePublishedExternalRoute(GetInstancePtr(), &prefix, &config);
|
||||
ExitNow();
|
||||
}
|
||||
#endif // OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE
|
||||
|
||||
error = OT_ERROR_INVALID_ARGS;
|
||||
|
||||
@@ -92,6 +92,14 @@ otError otNetDataPublishExternalRoute(otInstance *aInstance, const otExternalRou
|
||||
NetworkData::Publisher::kFromUser);
|
||||
}
|
||||
|
||||
otError otNetDataReplacePublishedExternalRoute(otInstance *aInstance,
|
||||
const otIp6Prefix *aPrefix,
|
||||
const otExternalRouteConfig *aConfig)
|
||||
{
|
||||
return AsCoreType(aInstance).Get<NetworkData::Publisher>().ReplacePublishedExternalRoute(
|
||||
AsCoreType(aPrefix), AsCoreType(aConfig), NetworkData::Publisher::kFromUser);
|
||||
}
|
||||
|
||||
bool otNetDataIsPrefixAdded(otInstance *aInstance, const otIp6Prefix *aPrefix)
|
||||
{
|
||||
return AsCoreType(aInstance).Get<NetworkData::Publisher>().IsPrefixAdded(AsCoreType(aPrefix));
|
||||
|
||||
@@ -276,10 +276,16 @@ public:
|
||||
* Thread Network Data.
|
||||
*
|
||||
* If there is a previously published route entry matching @p aPrefix, it will be replaced with the new prefix from
|
||||
* @p aConfig. In particular, if the @p aPrefix was already added in the Network Data, the change to the new prefix
|
||||
* in @p aConfig is immediately reflected in the Network Data (i.e., @p aPrefix is removed and the new prefix is
|
||||
* added in the same Network Data registration request to leader). This ensures that route entries in the Network
|
||||
* Data are not abruptly removed and the transition from @p aPrefix to new prefix is smooth.
|
||||
* @p aConfig.
|
||||
*
|
||||
* - If the @p aPrefix was already added in the Network Data, the change to the new prefix in @p aConfig is
|
||||
* immediately reflected in the Network Data. This ensures that route entries in the Network Data are not
|
||||
* abruptly removed and the transition from aPrefix to the new prefix is smooth.
|
||||
*
|
||||
* - If the old published @p aPrefix was not added in the Network Data, it will be replaced with the new @p aConfig
|
||||
* prefix but it will not be immediately added. Instead, it will start the process of publishing it in the
|
||||
* Network Data (monitoring the Network Data to determine when/if to add the prefix, depending on the number of
|
||||
* similar prefixes present in the Network Data).
|
||||
*
|
||||
* @param[in] aPrefix The previously published external route prefix to replace.
|
||||
* @param[in] aConfig The external route config to publish.
|
||||
|
||||
@@ -2380,6 +2380,10 @@ class NodeImpl:
|
||||
self.send_command(f'netdata publish route {prefix} {flags} {prf}')
|
||||
self._expect_done()
|
||||
|
||||
def netdata_publish_replace(self, old_prefix, prefix, flags='s', prf='med'):
|
||||
self.send_command(f'netdata publish replace {old_prefix} {prefix} {flags} {prf}')
|
||||
self._expect_done()
|
||||
|
||||
def netdata_unpublish_prefix(self, prefix):
|
||||
self.send_command(f'netdata unpublish {prefix}')
|
||||
self._expect_done()
|
||||
|
||||
@@ -461,6 +461,19 @@ class NetDataPublisher(thread_cert.TestCase):
|
||||
routes = leader.get_routes()
|
||||
self.check_num_of_routes(routes, num - 1, 0, 1)
|
||||
|
||||
# Replace the published route on leader with '::/0'.
|
||||
leader.netdata_publish_replace(EXTERNAL_ROUTE, '::/0', EXTERNAL_FLAGS, 'med')
|
||||
self.simulator.go(0.2)
|
||||
routes = leader.get_routes()
|
||||
self.assertEqual([route.split(' ')[0] == '::/0' for route in routes].count(True), 1)
|
||||
self.check_num_of_routes(routes, num - 1, 1, 0)
|
||||
|
||||
# Replace it back to the original route.
|
||||
leader.netdata_publish_replace('::/0', EXTERNAL_ROUTE, EXTERNAL_FLAGS, 'high')
|
||||
self.simulator.go(WAIT_TIME)
|
||||
routes = leader.get_routes()
|
||||
self.check_num_of_routes(routes, num - 1, 0, 1)
|
||||
|
||||
# Publish the same prefix on leader as an on-mesh prefix. Make
|
||||
# sure it is removed from external routes and now seen in the
|
||||
# prefix list.
|
||||
|
||||
Reference in New Issue
Block a user