mirror of
https://github.com/espressif/openthread.git
synced 2026-08-17 16:09:51 +00:00
[dua] remove OPENTHREAD_CONFIG_DUA_ENABLE build feature (#13165)
This commit completely removes the local Domain Unicast Address (DUA) registration feature flag (OPENTHREAD_CONFIG_DUA_ENABLE) and all of its associated implementation, public APIs, CLI commands, Spinel property handlers, and certification tests. Thread 1.2 FTD Border Router/Router DUA proxying features for MTD children (OPENTHREAD_CONFIG_TMF_PROXY_DUA_ENABLE) are preserved and updated to only compile/instantiate components when proxy DUA features are active. Detailed Changes: - Remove default definition of OPENTHREAD_CONFIG_DUA_ENABLE from misc.h. - Remove OT_DUA and openthread_config_dua_enable from CMake/GN configs. - Remove otThreadSetFixedDuaInterfaceIdentifier and otThreadGetFixedDuaInterfaceIdentifier from include/openthread/thread.h and implementation src/core/api/thread_api.cpp. - Remove CLI DUA interpreter from src/cli/cli.cpp. - Remove SPINEL_CAP_DUA capability and SPINEL_PROP_THREAD_DUA_ID Spinel property handlers and dispatchers from NCP. - Strip local DUA management features (conflict checking, SLAAC DUA interface identifiers, and dad info settings) from DuaManager, MLE, Address Resolver, and settings. - Clean up Notifier, TimeTicker, and TMF dispatcher guards. - Clean up -DOT_DUA=ON compilation flags across build/test scripts. - Delete obsolete DUA certification tests: - v1_2_test_domain_unicast_address - v1_2_test_domain_unicast_address_registration - v1_2_test_dua_handle_address_error
This commit is contained in:
@@ -1,320 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# Copyright (c) 2020, The OpenThread Authors.
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
# 1. Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# 2. Redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in the
|
||||
# documentation and/or other materials provided with the distribution.
|
||||
# 3. Neither the name of the copyright holder nor the
|
||||
# names of its contributors may be used to endorse or promote products
|
||||
# derived from this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS'
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
#
|
||||
|
||||
import unittest
|
||||
|
||||
import command
|
||||
import config
|
||||
import ipaddress
|
||||
import mle
|
||||
import thread_cert
|
||||
|
||||
BBR_1 = 1 # Collapsed with Leader Role
|
||||
ROUTER_1_1 = 2
|
||||
ROUTER_1_2 = 3
|
||||
MED_1_2 = 4
|
||||
SED_1_2 = 5
|
||||
|
||||
WAIT_ATTACH = 5
|
||||
WAIT_REDUNDANCE = 3
|
||||
ROUTER_SELECTION_JITTER = 1
|
||||
BBR_REGISTRATION_JITTER = 5
|
||||
SED_POLL_PERIOD = 2000 # 2s
|
||||
MED_TIMEOUT = 20 # 20s
|
||||
|
||||
DUA_IID_MANUAL1 = '4444333322221111'
|
||||
DUA_IID_MANUAL2 = '5555444433332222'
|
||||
|
||||
TEST_PREFIX1 = '2001:0:0:1::/64'
|
||||
TEST_PREFIX2 = '2001:0:0:2::/64'
|
||||
TEST_PREFIX3 = '2001:0:0:3::/64'
|
||||
"""
|
||||
Topology
|
||||
|
||||
|
||||
SED_1_2
|
||||
|
|
||||
|
|
||||
ROUTER_1_1 MED_1_2
|
||||
| |
|
||||
| |
|
||||
BBR_1 (LEADER) --- ROUTER_1_2
|
||||
|
||||
|
||||
1) Bring up BBR_1, BBR_1 becomes Leader and Primary Backbone Router, with Domain
|
||||
Prefix without `P_slaac`.
|
||||
|
||||
2) Bring up ROUTER_1_1, no DUA was added due to that `P_slaac` flag is not set.
|
||||
|
||||
3) Bring up ROUTER_1_2, verify that it has DUA generated.
|
||||
|
||||
4) Bring up MED_1_2 with DUA_IID_MANUAL1 set in advance, verify
|
||||
a) DUA_IID_MANUAL1 is registered in Address Registration TLV via Child Update Request.
|
||||
b) Remove DUA_IID_MANUAL1, a new DUA generated via SLAAC would be registered in Address
|
||||
Registration TLV via Child Update Request.
|
||||
c) Set DUA_IID_MANUAL2 which should override the generated one and be registered in Address
|
||||
Registration TLV via Child Update Request.
|
||||
d) Remove DUA_IID_MANUAL2, a new DUA generated via SLAAC, the same as in above b) would
|
||||
be registered in Address Registration TLV via Child Update Request.
|
||||
|
||||
5) Change BBR_1 from config.DOMAIN_PREFIX to config.DOMAIN_PRFIX_ALTER. Verify that MED_1_2
|
||||
generate a new Interface Identifier different from the one generated in 4d) due to the
|
||||
Domain Prefix change.
|
||||
|
||||
6) Recover config.Domain_Prefix on BBR_1. Verify that MED_1_2 generates and registers the same
|
||||
DUA as in step 4b).
|
||||
|
||||
7) Configure ROUTER_1_1 as Border Router with 3 SLAAC prefixes, verify MED_1_2 would register
|
||||
its DUA in Address Registration TLV.
|
||||
|
||||
8) Bring up SED_1_2, verify it generates one DUA, and registers it to its parent, though the parent
|
||||
is a Thread 1.1 device.
|
||||
|
||||
"""
|
||||
|
||||
|
||||
class TestDomainUnicastAddress(thread_cert.TestCase):
|
||||
TOPOLOGY = {
|
||||
BBR_1: {
|
||||
'version': '1.2',
|
||||
'allowlist': [ROUTER_1_1, ROUTER_1_2],
|
||||
'is_bbr': True
|
||||
},
|
||||
ROUTER_1_1: {
|
||||
'version': '1.1',
|
||||
'allowlist': [BBR_1, SED_1_2]
|
||||
},
|
||||
ROUTER_1_2: {
|
||||
'version': '1.2',
|
||||
'allowlist': [BBR_1, MED_1_2]
|
||||
},
|
||||
MED_1_2: {
|
||||
'mode': 'rn',
|
||||
'version': '1.2',
|
||||
'allowlist': [ROUTER_1_2],
|
||||
},
|
||||
SED_1_2: {
|
||||
'mode': 'n',
|
||||
'version': '1.2',
|
||||
'allowlist': [ROUTER_1_1],
|
||||
},
|
||||
}
|
||||
"""All nodes are created with default configurations"""
|
||||
|
||||
def __get_iid(self, address):
|
||||
''' Get the interface identifier of an IPv6 address.
|
||||
|
||||
Args:
|
||||
address (string): An IPv6 address;
|
||||
'''
|
||||
return ''.join(ipaddress.ip_address(address).exploded.split(':')[4:])
|
||||
|
||||
def __check_dua_registration(self, node, iid, dp_cid):
|
||||
''' Check whether or not the specified Domain Unicast Address is registered in Address
|
||||
Registration TLV.
|
||||
|
||||
Args:
|
||||
node (int) : The device id
|
||||
iid (string): The Interface Identifier
|
||||
dp_cid (int): The context id of the domain prefix.
|
||||
'''
|
||||
|
||||
messages = self.simulator.get_messages_sent_by(node)
|
||||
msg = messages.next_mle_message(mle.CommandType.CHILD_UPDATE_REQUEST)
|
||||
command.check_compressed_address_registration_tlv(msg, dp_cid, iid, cid_present_once=True)
|
||||
|
||||
def test(self):
|
||||
# starting context id
|
||||
context_id = 1
|
||||
|
||||
# 1) Bring up BBR_1, BBR_1 becomes Leader and Primary Backbone Router, with Domain
|
||||
# Prefix without `P_slaac`.
|
||||
self.nodes[BBR_1].set_router_selection_jitter(ROUTER_SELECTION_JITTER)
|
||||
self.nodes[BBR_1].set_bbr_registration_jitter(BBR_REGISTRATION_JITTER)
|
||||
self.nodes[BBR_1].set_backbone_router(seqno=1)
|
||||
self.nodes[BBR_1].start()
|
||||
WAIT_TIME = WAIT_ATTACH + ROUTER_SELECTION_JITTER
|
||||
self.simulator.go(WAIT_TIME * 2)
|
||||
self.assertEqual(self.nodes[BBR_1].get_state(), 'leader')
|
||||
self.nodes[BBR_1].enable_backbone_router()
|
||||
WAIT_TIME = BBR_REGISTRATION_JITTER + WAIT_REDUNDANCE
|
||||
self.simulator.go(WAIT_TIME)
|
||||
self.assertEqual(self.nodes[BBR_1].get_backbone_router_state(), 'Primary')
|
||||
|
||||
self.nodes[BBR_1].set_domain_prefix(config.DOMAIN_PREFIX, 'prosD')
|
||||
WAIT_TIME = WAIT_REDUNDANCE
|
||||
self.simulator.go(WAIT_TIME)
|
||||
|
||||
self.simulator.set_lowpan_context(context_id, config.DOMAIN_PREFIX)
|
||||
domain_prefix_cid = context_id
|
||||
|
||||
# 2) Bring up ROUTER_1_1, no DUA was added due to that `P_slaac` flag is not set.
|
||||
self.nodes[ROUTER_1_1].set_router_selection_jitter(ROUTER_SELECTION_JITTER)
|
||||
WAIT_TIME = WAIT_ATTACH + ROUTER_SELECTION_JITTER
|
||||
self.nodes[ROUTER_1_1].start()
|
||||
self.simulator.go(WAIT_TIME)
|
||||
self.assertEqual(self.nodes[ROUTER_1_1].get_state(), 'router')
|
||||
dua = self.nodes[ROUTER_1_1].get_addr(config.DOMAIN_PREFIX)
|
||||
assert not dua, 'Error: Unexpected DUA ({})'.format(dua)
|
||||
|
||||
# 3) Bring up ROUTER_1_2, verify that it has DUA generated.
|
||||
self.nodes[ROUTER_1_2].set_router_selection_jitter(ROUTER_SELECTION_JITTER)
|
||||
self.nodes[ROUTER_1_2].start()
|
||||
WAIT_TIME = WAIT_ATTACH + ROUTER_SELECTION_JITTER
|
||||
self.simulator.go(WAIT_TIME)
|
||||
self.assertEqual(self.nodes[ROUTER_1_2].get_state(), 'router')
|
||||
dua = self.nodes[ROUTER_1_2].get_addr(config.DOMAIN_PREFIX)
|
||||
assert dua, 'Error: Expected DUA not found'
|
||||
self.assertTrue(self.nodes[BBR_1].ping(dua))
|
||||
|
||||
# 4) Bring up MED_1_2 with DUA_IID_MANUAL1 set in advance
|
||||
self.nodes[MED_1_2].set_dua_iid(DUA_IID_MANUAL1)
|
||||
self.nodes[MED_1_2].set_timeout(MED_TIMEOUT)
|
||||
self.nodes[MED_1_2].start()
|
||||
WAIT_TIME = WAIT_ATTACH
|
||||
self.simulator.go(WAIT_TIME)
|
||||
self.assertEqual(self.nodes[MED_1_2].get_state(), 'child')
|
||||
|
||||
# 4a) DUA_IID_MANUAL1 is registered in Address Registration TLV via Child Update Request.
|
||||
self.__check_dua_registration(MED_1_2, DUA_IID_MANUAL1, domain_prefix_cid)
|
||||
|
||||
# 4b) Remove DUA_IID_MANUAL1, a new DUA generated via SLAAC would be registered in Address
|
||||
# Registration TLV via Child Update Request.
|
||||
|
||||
# Flush relative message queues.
|
||||
messages = self.simulator.get_messages_sent_by(MED_1_2)
|
||||
|
||||
self.nodes[MED_1_2].clear_dua_iid()
|
||||
WAIT_TIME = MED_TIMEOUT + WAIT_REDUNDANCE
|
||||
self.simulator.go(WAIT_TIME)
|
||||
|
||||
med_1_2_dua = self.nodes[MED_1_2].get_addr(config.DOMAIN_PREFIX)
|
||||
assert med_1_2_dua, 'Error: Expected DUA not found'
|
||||
|
||||
med_1_2_dua_iid = self.__get_iid(med_1_2_dua)
|
||||
self.__check_dua_registration(MED_1_2, med_1_2_dua_iid, domain_prefix_cid)
|
||||
|
||||
# 4c) Set DUA_IID_MANUAL2 which should override the generated one and be registered in Address
|
||||
# Registration TLV via Child Update Request.
|
||||
|
||||
# Flush relative message queues.
|
||||
messages = self.simulator.get_messages_sent_by(MED_1_2)
|
||||
self.nodes[MED_1_2].set_dua_iid(DUA_IID_MANUAL2)
|
||||
WAIT_TIME = WAIT_REDUNDANCE
|
||||
self.simulator.go(WAIT_TIME)
|
||||
|
||||
dua = self.nodes[MED_1_2].get_addr(config.DOMAIN_PREFIX)
|
||||
|
||||
self.__check_dua_registration(MED_1_2, DUA_IID_MANUAL2, domain_prefix_cid)
|
||||
|
||||
# 4d) Remove DUA_IID_MANUAL2, a new DUA generated via SLAAC, the same as in above b) would
|
||||
# be registered in Address Registration TLV via Child Update Request.
|
||||
|
||||
# Flush relative message queues.
|
||||
messages = self.simulator.get_messages_sent_by(MED_1_2)
|
||||
self.nodes[MED_1_2].clear_dua_iid()
|
||||
WAIT_TIME = WAIT_REDUNDANCE
|
||||
self.simulator.go(WAIT_TIME)
|
||||
dua = self.nodes[MED_1_2].get_addr(config.DOMAIN_PREFIX)
|
||||
self.assertEqual(ipaddress.ip_address(dua), ipaddress.ip_address(med_1_2_dua))
|
||||
self.assertEqual(ipaddress.ip_address(med_1_2_dua), ipaddress.ip_address(dua))
|
||||
|
||||
self.__check_dua_registration(MED_1_2, med_1_2_dua_iid, domain_prefix_cid)
|
||||
|
||||
# 5) Change BBR_1 from config.DOMAIN_PREFIX to config.DOMAIN_PRFIX_ALTER. Verify that MED_1_2
|
||||
# generates a new Interface Identifier different from the one generated in 4d) due to the
|
||||
# Domain Prefix change.
|
||||
context_id += 1
|
||||
self.simulator.set_lowpan_context(context_id, config.DOMAIN_PREFIX_ALTER)
|
||||
self.nodes[BBR_1].set_domain_prefix(config.DOMAIN_PREFIX_ALTER)
|
||||
WAIT_TIME = WAIT_REDUNDANCE
|
||||
self.simulator.go(WAIT_TIME)
|
||||
|
||||
med_1_2_dua2 = self.nodes[MED_1_2].get_addr(config.DOMAIN_PREFIX_ALTER)
|
||||
med_1_2_dua2_iid = self.__get_iid(med_1_2_dua2)
|
||||
self.__check_dua_registration(MED_1_2, med_1_2_dua2_iid, context_id)
|
||||
|
||||
#6) Recover config.Domain_Prefix on BBR_1. Verify that MED_1_2 generates and registers the same
|
||||
# DUA as in step 4b).
|
||||
self.nodes[BBR_1].set_domain_prefix(config.DOMAIN_PREFIX)
|
||||
WAIT_TIME = WAIT_REDUNDANCE
|
||||
self.simulator.go(WAIT_TIME)
|
||||
dua = self.nodes[MED_1_2].get_addr(config.DOMAIN_PREFIX)
|
||||
assert dua, 'Error: Expected DUA not found'
|
||||
self.assertEqual(ipaddress.ip_address(med_1_2_dua), ipaddress.ip_address(dua))
|
||||
|
||||
self.__check_dua_registration(MED_1_2, med_1_2_dua_iid, domain_prefix_cid)
|
||||
|
||||
#7) Configure ROUTER_1_1 as Border Router with 3 SLAAC prefixes, verify MED_1_2 would register
|
||||
# its DUA in Address Registration TLV.
|
||||
|
||||
# Flush relative message queues.
|
||||
messages = self.simulator.get_messages_sent_by(MED_1_2)
|
||||
|
||||
context_id += 1
|
||||
self.simulator.set_lowpan_context(context_id, TEST_PREFIX1)
|
||||
self.nodes[ROUTER_1_1].add_prefix(TEST_PREFIX1)
|
||||
|
||||
context_id += 1
|
||||
self.simulator.set_lowpan_context(context_id, TEST_PREFIX2)
|
||||
self.nodes[ROUTER_1_1].add_prefix(TEST_PREFIX2)
|
||||
context_id += 1
|
||||
self.simulator.set_lowpan_context(context_id, TEST_PREFIX3)
|
||||
self.nodes[ROUTER_1_1].add_prefix(TEST_PREFIX3)
|
||||
self.nodes[ROUTER_1_1].register_netdata()
|
||||
|
||||
WAIT_TIME = WAIT_REDUNDANCE
|
||||
self.simulator.go(WAIT_TIME)
|
||||
|
||||
WAIT_TIME = MED_TIMEOUT
|
||||
self.simulator.go(WAIT_TIME)
|
||||
dua = self.nodes[MED_1_2].get_addr(config.DOMAIN_PREFIX)
|
||||
assert dua, 'Error: Expected DUA not found'
|
||||
self.assertEqual(ipaddress.ip_address(med_1_2_dua), ipaddress.ip_address(dua))
|
||||
|
||||
self.__check_dua_registration(MED_1_2, med_1_2_dua_iid, domain_prefix_cid)
|
||||
|
||||
#8) Bring up SED_1_2, verify that it generates one DUA, and registers it to its parent, though the parent
|
||||
# is a Thread 1.1 device.
|
||||
self.nodes[SED_1_2].set_pollperiod(SED_POLL_PERIOD)
|
||||
self.nodes[SED_1_2].start()
|
||||
WAIT_TIME = WAIT_ATTACH
|
||||
self.simulator.go(WAIT_TIME)
|
||||
|
||||
dua = self.nodes[SED_1_2].get_addr(config.DOMAIN_PREFIX)
|
||||
assert dua, 'Error: Expected DUA not found'
|
||||
|
||||
dua_iid = self.__get_iid(dua)
|
||||
self.__check_dua_registration(SED_1_2, dua_iid, domain_prefix_cid)
|
||||
|
||||
self.assertTrue(self.nodes[BBR_1].ping(dua))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
@@ -1,370 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# Copyright (c) 2020, The OpenThread Authors.
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
# 1. Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# 2. Redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in the
|
||||
# documentation and/or other materials provided with the distribution.
|
||||
# 3. Neither the name of the copyright holder nor the
|
||||
# names of its contributors may be used to endorse or promote products
|
||||
# derived from this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS'
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
#
|
||||
|
||||
import unittest
|
||||
|
||||
import command
|
||||
import config
|
||||
import ipaddress
|
||||
import mle
|
||||
import network_layer
|
||||
import thread_cert
|
||||
|
||||
BBR_1 = 1 # Collapsed with Leader Role
|
||||
ROUTER_1_1 = 2
|
||||
ROUTER_1_2 = 3
|
||||
|
||||
FED_1_2_1 = 4
|
||||
MED_1_2_1 = 5
|
||||
SED_1_2_1 = 6
|
||||
|
||||
FED_1_2_2 = 7
|
||||
MED_1_2_2 = 8
|
||||
SED_1_2_2 = 9
|
||||
|
||||
WAIT_ATTACH = 5
|
||||
WAIT_REDUNDANCE = 3
|
||||
ROUTER_SELECTION_JITTER = 1
|
||||
BBR_REGISTRATION_JITTER = 5
|
||||
SED_POLL_PERIOD = 2000 # 2s
|
||||
MED_TIMEOUT = 20 # 20s
|
||||
PARENT_AGGREGATE_DELAY = 5 # 5s
|
||||
|
||||
DUA_IID_MANUAL1 = '4444333322221111'
|
||||
|
||||
ST_DUA_SUCCESS = 0
|
||||
ST_DUA_REREGISTER = 1
|
||||
ST_DUA_INVALID = 2
|
||||
ST_DUA_DUPLICATE = 3
|
||||
ST_DUA_NO_RESOURCES = 4
|
||||
ST_DUA_BBR_NOT_PRIMARY = 5
|
||||
ST_DUA_GENERAL_FAILURE = 6
|
||||
|
||||
BBR_REREGISTRATION_DELAY = 10
|
||||
"""
|
||||
Topology
|
||||
|
||||
|
||||
MED_1_2_1 SED_1_2_1
|
||||
\ |
|
||||
\ |
|
||||
FED_1_2_1 --- ROUTER_1_1 FED_1_2_2 MED_1_2_2
|
||||
| | /
|
||||
| | /
|
||||
BBR_1 (LEADER) --- ROUTER_1_2 --- SED_1_2_2
|
||||
|
||||
|
||||
1) Bring up BBR_1, BBR_1 becomes Leader and Primary Backbone Router, with Domain
|
||||
Prefix without `P_slaac`.
|
||||
|
||||
2) Test behaviors of ROUTER_1_2 under various response status:
|
||||
a) Bring up ROUTER_1_2 with DUA_IID_MANUAL1, one DUA.req should happen to register DUA.
|
||||
b) Remove DUA_IID_MANUAL1, one DUA.req should happen for the new generated DUA via SLAAC.
|
||||
c) Configure BBR_1 to respond with the fatal error ST_DUA_INVALID, update BBR_1 with
|
||||
BBR_REREGISTRATION_DELAY, ROUTER_1_2 should re-register its DUA within BBR_REREGISTRATION_DELAY.
|
||||
- ROUTER_1_2 should remove its dua
|
||||
- update network data, ROUTER_1_2 would regenerate and register the same dua
|
||||
d) Configure BBR_1 to respond with the fatal error ST_DUA_DUPLICATE, update seqno to trigger reregistration.
|
||||
After received DUA.rsp with ST_DUA_DUPLICATE, ROUTER_1_2 should
|
||||
- increase dad counter
|
||||
- regenerate a new DUA
|
||||
- send DUA.req
|
||||
e) (repeated) Configure BBR_1 to respond with per remaining error status:
|
||||
- increase BBR seqno to trigger reregistration
|
||||
- ROUTER_1_2 should re-register within BBR_REREGISTRATION_DELAY. For the not fatal errors, ROUTER_1_2
|
||||
should re-register within another BBR_REREGISTRATION_DELAY (with least delay if ST_DUA_REREGISTER)
|
||||
3) Bring up FED_1_2_1, MED_1_2_1, SED_1_2_1, they should send DUA.req by themselves as the parent
|
||||
is of Thread 1.1 version.
|
||||
4) Bring up FED_1_2_2, it sends DUA.req itself as it it FTD.
|
||||
5) MED_1_2_2, SED_1_2_2, MTDs should should register their DUA to their parent
|
||||
by Child Update Request, and the parent would send DUA.req for them on behalf.
|
||||
6) Increase seqno on BBR_1, within BBR_REREGISTRATION_DELAY, there should be one DUA.req from
|
||||
per [FED_1_2_1, MED_1_2_1, SED_1_2_1, FED_1_2_2], and 3 DUA.req from ROUTER_1_2 among which
|
||||
2 DUA.req are for its MTD children.
|
||||
|
||||
"""
|
||||
|
||||
|
||||
class TestDomainUnicastAddressRegistration(thread_cert.TestCase):
|
||||
TOPOLOGY = {
|
||||
BBR_1: {
|
||||
'version': '1.2',
|
||||
'allowlist': [ROUTER_1_1, ROUTER_1_2],
|
||||
'is_bbr': True
|
||||
},
|
||||
ROUTER_1_1: {
|
||||
'version': '1.1',
|
||||
'allowlist': [BBR_1, FED_1_2_1, MED_1_2_1, SED_1_2_1]
|
||||
},
|
||||
ROUTER_1_2: {
|
||||
'version': '1.2',
|
||||
'allowlist': [BBR_1, FED_1_2_2, MED_1_2_2, SED_1_2_2]
|
||||
},
|
||||
FED_1_2_1: {
|
||||
'version': '1.2',
|
||||
'allowlist': [ROUTER_1_1],
|
||||
},
|
||||
MED_1_2_1: {
|
||||
'mode': 'rn',
|
||||
'version': '1.2',
|
||||
'allowlist': [ROUTER_1_1],
|
||||
},
|
||||
SED_1_2_1: {
|
||||
'mode': 'n',
|
||||
'version': '1.2',
|
||||
'allowlist': [ROUTER_1_1],
|
||||
},
|
||||
FED_1_2_2: {
|
||||
'version': '1.2',
|
||||
'allowlist': [ROUTER_1_2],
|
||||
},
|
||||
MED_1_2_2: {
|
||||
'mode': 'rn',
|
||||
'version': '1.2',
|
||||
'allowlist': [ROUTER_1_2],
|
||||
},
|
||||
SED_1_2_2: {
|
||||
'mode': 'n',
|
||||
'version': '1.2',
|
||||
'allowlist': [ROUTER_1_2],
|
||||
},
|
||||
}
|
||||
"""All nodes are created with default configurations"""
|
||||
|
||||
def __get_iid(self, address):
|
||||
''' Get the interface identifier of an IPv6 address.
|
||||
|
||||
Args:
|
||||
address (string): An IPv6 address;
|
||||
'''
|
||||
return ''.join(ipaddress.ip_address(address).exploded.split(':')[4:])
|
||||
|
||||
def __check_dua_registration_tmf(self, node, occurrences=1, ml_eid=None):
|
||||
|
||||
messages = self.simulator.get_messages_sent_by(node)
|
||||
for i in range(occurrences):
|
||||
msg = messages.next_coap_message('0.02', '/n/dr', False)
|
||||
assert msg, 'Expected {}, but {}th not found\n node: {}(extaddr: {})'.format(
|
||||
occurrences, i + 1, node, self.nodes[node].get_addr64())
|
||||
if ml_eid:
|
||||
ml_eid_tlv = msg.get_coap_message_tlv(network_layer.MlEid)
|
||||
self.assertEqual(ml_eid, ml_eid_tlv.ml_eid.hex())
|
||||
|
||||
def test(self):
|
||||
# starting context id
|
||||
context_id = 1
|
||||
seq_num = 1
|
||||
|
||||
# 1) Bring up BBR_1, BBR_1 becomes Leader and Primary Backbone Router, with Domain
|
||||
# Prefix without `P_slaac`.
|
||||
self.nodes[BBR_1].set_router_selection_jitter(ROUTER_SELECTION_JITTER)
|
||||
self.nodes[BBR_1].set_bbr_registration_jitter(BBR_REGISTRATION_JITTER)
|
||||
self.nodes[BBR_1].set_backbone_router(seqno=seq_num, reg_delay=BBR_REREGISTRATION_DELAY)
|
||||
self.nodes[BBR_1].start()
|
||||
WAIT_TIME = WAIT_ATTACH + ROUTER_SELECTION_JITTER
|
||||
self.simulator.go(WAIT_TIME * 2)
|
||||
self.assertEqual(self.nodes[BBR_1].get_state(), 'leader')
|
||||
self.nodes[BBR_1].enable_backbone_router()
|
||||
WAIT_TIME = BBR_REGISTRATION_JITTER + WAIT_REDUNDANCE
|
||||
self.simulator.go(WAIT_TIME)
|
||||
self.assertEqual(self.nodes[BBR_1].get_backbone_router_state(), 'Primary')
|
||||
|
||||
self.nodes[BBR_1].set_domain_prefix(config.DOMAIN_PREFIX, 'prosD')
|
||||
WAIT_TIME = WAIT_REDUNDANCE
|
||||
self.simulator.go(WAIT_TIME)
|
||||
|
||||
self.simulator.set_lowpan_context(context_id, config.DOMAIN_PREFIX)
|
||||
domain_prefix_cid = context_id
|
||||
|
||||
# 2) Test behaviors of ROUTER_1_2 under various response status:
|
||||
# a) Bring up ROUTER_1_2 with DUA_IID_MANUAL1, one DUA.req should happen to register DUA.
|
||||
|
||||
# Flush relative message queues.
|
||||
self.flush_nodes([ROUTER_1_2])
|
||||
|
||||
self.nodes[ROUTER_1_2].set_dua_iid(DUA_IID_MANUAL1)
|
||||
self.nodes[ROUTER_1_2].set_router_selection_jitter(ROUTER_SELECTION_JITTER)
|
||||
self.nodes[ROUTER_1_2].start()
|
||||
WAIT_TIME = WAIT_ATTACH
|
||||
self.simulator.go(WAIT_TIME)
|
||||
self.assertEqual(self.nodes[ROUTER_1_2].get_state(), 'router')
|
||||
|
||||
mliid = self.__get_iid(self.nodes[ROUTER_1_2].get_mleid())
|
||||
|
||||
WAIT_TIME = WAIT_ATTACH + WAIT_REDUNDANCE
|
||||
self.simulator.go(WAIT_TIME)
|
||||
self.__check_dua_registration_tmf(ROUTER_1_2, 1, self.nodes[ROUTER_1_2].get_mleid_iid())
|
||||
|
||||
# b) Remove DUA_IID_MANUAL1, one DUA.req should happen for the new generated DUA via SLAAC.
|
||||
|
||||
# Flush relative message queues.
|
||||
self.flush_nodes([ROUTER_1_2])
|
||||
self.nodes[ROUTER_1_2].clear_dua_iid()
|
||||
WAIT_TIME = WAIT_ATTACH + WAIT_REDUNDANCE
|
||||
self.simulator.go(WAIT_TIME)
|
||||
self.__check_dua_registration_tmf(ROUTER_1_2, 1, self.nodes[ROUTER_1_2].get_mleid_iid())
|
||||
|
||||
#c) Configure BBR_1 to respond with the fatal error ST_DUA_INVALID, update BBR_1 with
|
||||
# BBR_REREGISTRATION_DELAY, ROUTER_1_2 should re-register its DUA within BBR_REREGISTRATION_DELAY.
|
||||
# - ROUTER_1_2 should remove its dua
|
||||
# - update network data, ROUTER_1_2 would regenerate and register the same dua
|
||||
|
||||
# Flush relative message queues.
|
||||
self.flush_nodes([ROUTER_1_2])
|
||||
seq_num = seq_num + 1
|
||||
self.nodes[BBR_1].set_next_dua_response(ST_DUA_INVALID, mliid)
|
||||
self.nodes[BBR_1].set_backbone_router(seqno=seq_num)
|
||||
WAIT_TIME = BBR_REREGISTRATION_DELAY + WAIT_REDUNDANCE
|
||||
self.simulator.go(WAIT_TIME)
|
||||
|
||||
self.__check_dua_registration_tmf(ROUTER_1_2, 1, self.nodes[ROUTER_1_2].get_mleid_iid())
|
||||
dua = self.nodes[ROUTER_1_2].get_addr(config.DOMAIN_PREFIX)
|
||||
assert not dua, 'Error: Unexpected DUA ({}) found'.format(dua)
|
||||
|
||||
# Retry after new network data is available
|
||||
seq_num = seq_num + 1
|
||||
dua = self.nodes[ROUTER_1_2].get_addr(config.DOMAIN_PREFIX)
|
||||
self.nodes[BBR_1].set_backbone_router(seqno=seq_num)
|
||||
WAIT_TIME = BBR_REREGISTRATION_DELAY + WAIT_REDUNDANCE
|
||||
self.simulator.go(WAIT_TIME)
|
||||
|
||||
self.__check_dua_registration_tmf(ROUTER_1_2, 1, self.nodes[ROUTER_1_2].get_mleid_iid())
|
||||
dua = self.nodes[ROUTER_1_2].get_addr(config.DOMAIN_PREFIX)
|
||||
assert dua, 'Error: Expected DUA ({}) not found'.format(dua)
|
||||
|
||||
#d) Configure BBR_1 to respond with the fatal error ST_DUA_DUPLICATE, update seqno to trigger reregistration.
|
||||
# After received DUA.rsp with ST_DUA_DUPLICATE, ROUTER_1_2 should
|
||||
# - increase dad counter
|
||||
# - regenerate a new DUA
|
||||
# - send DUA.req
|
||||
|
||||
# Flush relative message queues.
|
||||
self.flush_nodes([ROUTER_1_2])
|
||||
seq_num = seq_num + 1
|
||||
self.nodes[BBR_1].set_next_dua_response(ST_DUA_DUPLICATE, mliid)
|
||||
self.nodes[BBR_1].set_backbone_router(seqno=seq_num)
|
||||
WAIT_TIME = BBR_REREGISTRATION_DELAY * 2 + WAIT_REDUNDANCE
|
||||
self.simulator.go(WAIT_TIME)
|
||||
|
||||
self.__check_dua_registration_tmf(ROUTER_1_2, 2, self.nodes[ROUTER_1_2].get_mleid_iid())
|
||||
|
||||
dua2 = self.nodes[ROUTER_1_2].get_addr(config.DOMAIN_PREFIX)
|
||||
assert dua2, 'Error: Expected DUA ({}) not found'.format(dua2)
|
||||
self.assertNotEqual(dua2, dua)
|
||||
|
||||
# e) (repeated) Configure BBR_1 to respond with per remaining error status:
|
||||
# - increase BBR seqno to trigger reregistration
|
||||
# - ROUTER_1_2 should re-register within BBR_REREGISTRATION_DELAY. For the not fatal errors, ROUTER_1_2
|
||||
# should re-register within another BBR_REREGISTRATION_DELAY (with least delay if ST_DUA_REREGISTER)
|
||||
for status in ['5.00', ST_DUA_REREGISTER, ST_DUA_NO_RESOURCES, ST_DUA_BBR_NOT_PRIMARY, ST_DUA_GENERAL_FAILURE]:
|
||||
print(f'Testing Status {status}...')
|
||||
# Flush relative message queues.
|
||||
self.flush_nodes([ROUTER_1_2])
|
||||
seq_num = seq_num + 1
|
||||
self.nodes[BBR_1].set_next_dua_response(status, mliid)
|
||||
self.nodes[BBR_1].set_backbone_router(seqno=seq_num)
|
||||
WAIT_TIME = BBR_REREGISTRATION_DELAY + WAIT_REDUNDANCE
|
||||
if status != ST_DUA_REREGISTER:
|
||||
WAIT_TIME += BBR_REREGISTRATION_DELAY
|
||||
|
||||
self.simulator.go(WAIT_TIME)
|
||||
|
||||
self.__check_dua_registration_tmf(ROUTER_1_2, 2, self.nodes[ROUTER_1_2].get_mleid_iid())
|
||||
|
||||
# Bring up Router_1_1
|
||||
self.nodes[ROUTER_1_1].set_router_selection_jitter(ROUTER_SELECTION_JITTER)
|
||||
self.nodes[ROUTER_1_1].start()
|
||||
WAIT_TIME = WAIT_ATTACH
|
||||
self.simulator.go(WAIT_TIME)
|
||||
self.assertEqual(self.nodes[ROUTER_1_1].get_state(), 'router')
|
||||
|
||||
dua = self.nodes[ROUTER_1_1].get_addr(config.DOMAIN_PREFIX)
|
||||
assert not dua, 'Error: Unexpected DUA ({}) found'.format(dua)
|
||||
|
||||
# Configure children
|
||||
for node in [FED_1_2_1, FED_1_2_2]:
|
||||
self.nodes[node].set_routereligible(False)
|
||||
|
||||
for node in [SED_1_2_1, SED_1_2_2]:
|
||||
self.nodes[node].set_pollperiod(SED_POLL_PERIOD)
|
||||
|
||||
for node in [MED_1_2_1, MED_1_2_2]:
|
||||
self.nodes[node].set_timeout(MED_TIMEOUT)
|
||||
|
||||
# 3) Bring up FED_1_2_1, MED_1_2_1, SED_1_2_1, they should send DUA.req by themselves as the parent
|
||||
# is of Thread 1.1 version.
|
||||
# 4) Bring up FED_1_2_2, it sends DUA.req itself as it it FTD.
|
||||
for node in [FED_1_2_1, MED_1_2_1, SED_1_2_1, FED_1_2_2]:
|
||||
print("Starting child {} (extaddr: {})...".format(node, self.nodes[node].get_addr64()))
|
||||
# Flush all message queues.
|
||||
self.flush_all()
|
||||
self.nodes[node].start()
|
||||
WAIT_TIME = WAIT_ATTACH
|
||||
self.simulator.go(WAIT_TIME)
|
||||
self.assertEqual(self.nodes[node].get_state(), 'child')
|
||||
WAIT_TIME = PARENT_AGGREGATE_DELAY + WAIT_REDUNDANCE
|
||||
self.simulator.go(WAIT_TIME)
|
||||
self.__check_dua_registration_tmf(node, 1, self.nodes[node].get_mleid_iid())
|
||||
|
||||
# 5) MED_1_2_2, SED_1_2_2, MTDs should should register their DUA to their parent
|
||||
# by Child Update Request, and the parent would send DUA.req for them on behalf.
|
||||
for node in [MED_1_2_2, SED_1_2_2]:
|
||||
print("Starting child {} (extaddr: {})...".format(node, self.nodes[node].get_addr64()))
|
||||
# Flush all message queues.
|
||||
self.flush_all()
|
||||
self.nodes[node].start()
|
||||
WAIT_TIME = WAIT_ATTACH
|
||||
self.simulator.go(WAIT_TIME)
|
||||
self.assertEqual(self.nodes[node].get_state(), 'child')
|
||||
|
||||
WAIT_TIME = PARENT_AGGREGATE_DELAY + WAIT_REDUNDANCE
|
||||
print("waiting {}".format(WAIT_TIME))
|
||||
self.simulator.go(WAIT_TIME)
|
||||
self.__check_dua_registration_tmf(ROUTER_1_2, 1, self.nodes[node].get_mleid_iid())
|
||||
|
||||
# 6) Increase seqno on BBR_1, within BBR_REREGISTRATION_DELAY, there should be one DUA.req from
|
||||
# per [FED_1_2_1, MED_1_2_1, SED_1_2_1, FED_1_2_2], and 3 DUA.req from ROUTER_1_2 among which
|
||||
# 2 DUA.req are for its MTD children.
|
||||
|
||||
# Flush all message queues.
|
||||
self.flush_all()
|
||||
seq_num = seq_num + 1
|
||||
self.nodes[BBR_1].set_backbone_router(seqno=seq_num)
|
||||
WAIT_TIME = BBR_REREGISTRATION_DELAY + WAIT_REDUNDANCE
|
||||
self.simulator.go(WAIT_TIME)
|
||||
WAIT_TIME = BBR_REREGISTRATION_DELAY + WAIT_REDUNDANCE
|
||||
self.simulator.go(WAIT_TIME)
|
||||
for node in [FED_1_2_1, MED_1_2_1, SED_1_2_1, FED_1_2_2]:
|
||||
self.__check_dua_registration_tmf(node, 1, self.nodes[node].get_mleid_iid())
|
||||
|
||||
self.__check_dua_registration_tmf(ROUTER_1_2, 3)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
@@ -1,148 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# Copyright (c) 2020, The OpenThread Authors.
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
# 1. Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# 2. Redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in the
|
||||
# documentation and/or other materials provided with the distribution.
|
||||
# 3. Neither the name of the copyright holder nor the
|
||||
# names of its contributors may be used to endorse or promote products
|
||||
# derived from this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS'
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
#
|
||||
# This script tests how node would handle duplicated Domain Unicast Address.
|
||||
#
|
||||
|
||||
import unittest
|
||||
|
||||
import config
|
||||
import thread_cert
|
||||
|
||||
BBR_1 = 1 # Collapsed with Leader Role
|
||||
ROUTER = 2
|
||||
FED = 3
|
||||
MED = 4
|
||||
|
||||
WAIT_ATTACH = 5
|
||||
WAIT_REDUNDANCE = 3
|
||||
BBR_REGISTRATION_JITTER = 5
|
||||
SED_POLL_PERIOD = 2000 # 2s
|
||||
MED_TIMEOUT = 20 # 20s
|
||||
"""
|
||||
Topology
|
||||
|
||||
BBR_1 (Leader)
|
||||
|
|
||||
ROUTER_1---FED
|
||||
|
|
||||
MED
|
||||
"""
|
||||
|
||||
WAIT_REDUNDANCE = 3
|
||||
REG_DELAY = 5
|
||||
|
||||
|
||||
class TestDomainUnicastAddress(thread_cert.TestCase):
|
||||
TOPOLOGY = {
|
||||
BBR_1: {
|
||||
'version': '1.2',
|
||||
'allowlist': [ROUTER],
|
||||
'is_bbr': True
|
||||
},
|
||||
ROUTER: {
|
||||
'version': '1.2',
|
||||
'allowlist': [BBR_1, FED, MED],
|
||||
},
|
||||
FED: {
|
||||
'version': '1.2',
|
||||
'allowlist': [ROUTER],
|
||||
'router_eligible': False,
|
||||
'mode': 'rdn',
|
||||
},
|
||||
MED: {
|
||||
'version': '1.2',
|
||||
'is_mtd': True,
|
||||
'allowlist': [ROUTER],
|
||||
'mode': 'rn',
|
||||
},
|
||||
}
|
||||
|
||||
def test(self):
|
||||
self.simulator.set_lowpan_context(1, config.DOMAIN_PREFIX)
|
||||
|
||||
# 1) Bring up BBR_1, BBR_1 becomes Leader and Primary Backbone Router, with Domain
|
||||
# Prefix without `P_slaac`.
|
||||
self.nodes[BBR_1].set_bbr_registration_jitter(BBR_REGISTRATION_JITTER)
|
||||
self.nodes[BBR_1].set_backbone_router(seqno=1, reg_delay=REG_DELAY)
|
||||
self.nodes[BBR_1].start()
|
||||
|
||||
self.simulator.go(WAIT_ATTACH * 2 + config.DEFAULT_ROUTER_SELECTION_JITTER)
|
||||
self.assertEqual(self.nodes[BBR_1].get_state(), 'leader')
|
||||
self.nodes[BBR_1].enable_backbone_router()
|
||||
self.simulator.go(BBR_REGISTRATION_JITTER + WAIT_REDUNDANCE)
|
||||
self.assertEqual(self.nodes[BBR_1].get_backbone_router_state(), 'Primary')
|
||||
|
||||
self.nodes[BBR_1].set_domain_prefix(config.DOMAIN_PREFIX, 'prosD')
|
||||
self.simulator.go(WAIT_REDUNDANCE)
|
||||
|
||||
# 2) Bring up ROUTER_1
|
||||
self.nodes[ROUTER].start()
|
||||
self.simulator.go(WAIT_ATTACH + REG_DELAY + WAIT_REDUNDANCE)
|
||||
self.assertEqual(self.nodes[ROUTER].get_state(), 'router')
|
||||
|
||||
# Bring up FED
|
||||
self.nodes[FED].start()
|
||||
self.simulator.go(WAIT_ATTACH + REG_DELAY + WAIT_REDUNDANCE)
|
||||
self.assertEqual(self.nodes[FED].get_state(), 'child')
|
||||
|
||||
# Bring up MED
|
||||
self.nodes[MED].start()
|
||||
self.simulator.go(WAIT_ATTACH + config.PARENT_AGGREGATIOIN_DELAY + REG_DELAY + WAIT_REDUNDANCE)
|
||||
self.assertEqual(self.nodes[MED].get_state(), 'child')
|
||||
|
||||
self._verify_dua_handle_address_error(ROUTER)
|
||||
self._verify_dua_handle_address_error(FED)
|
||||
self._verify_dua_handle_address_error(MED, is_med=True)
|
||||
|
||||
def _verify_dua_handle_address_error(self, nodeid, is_med=False):
|
||||
dua = self.nodes[nodeid].get_addr(config.DOMAIN_PREFIX)
|
||||
self.assertIsNotNone(dua)
|
||||
|
||||
# Ping the DUA to verify reachability, and also fill the EID cache on BBR_1
|
||||
self.assertTrue(self.nodes[BBR_1].ping(dua))
|
||||
|
||||
self.simulator.go(WAIT_REDUNDANCE)
|
||||
|
||||
# Send fake /a/an from ROUTER to BBR_1 for the node's DUA
|
||||
pbbr_rloc = self.nodes[BBR_1].get_ip6_address(config.ADDRESS_TYPE.RLOC)
|
||||
self.nodes[ROUTER].send_address_notification(pbbr_rloc, dua, f'000000000000{nodeid:04x}')
|
||||
|
||||
self.simulator.go(config.PARENT_AGGREGATIOIN_DELAY * is_med + REG_DELAY + WAIT_REDUNDANCE + 50)
|
||||
|
||||
# Make sure device handles /a/ae correctly by generating new DUA
|
||||
new_dua = self.nodes[nodeid].get_addr(config.DOMAIN_PREFIX)
|
||||
self.assertNotEqual(dua, new_dua)
|
||||
self.assertTrue(self.nodes[BBR_1].ping(new_dua))
|
||||
self.assertFalse(self.nodes[BBR_1].ping(dua))
|
||||
|
||||
self.simulator.go(3)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
Reference in New Issue
Block a user