1#!/usr/bin/env python3 2# 3# Copyright (c) 2024, The OpenThread Authors. 4# All rights reserved. 5# 6# Redistribution and use in source and binary forms, with or without 7# modification, are permitted provided that the following conditions are met: 8# 1. Redistributions of source code must retain the above copyright 9# notice, this list of conditions and the following disclaimer. 10# 2. Redistributions in binary form must reproduce the above copyright 11# notice, this list of conditions and the following disclaimer in the 12# documentation and/or other materials provided with the distribution. 13# 3. Neither the name of the copyright holder nor the 14# names of its contributors may be used to endorse or promote products 15# derived from this software without specific prior written permission. 16# 17# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' 18# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 21# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 27# POSSIBILITY OF SUCH DAMAGE. 28# 29 30import unittest 31import ipaddress 32 33import config 34import thread_cert 35 36from node import OtbrNode 37 38IPV4_CIDR_ADDR_CMD = f'ip addr show {config.BACKBONE_IFNAME} | grep -w inet | grep -Eo "[0-9.]+/[0-9]+"' 39 40 41class ThreeBRs_TwoInfra(thread_cert.TestCase): 42 """ 43 Test that two border routers on different infrastructures can ping each other via Thread interface. 44 45 Topology: 46 47 ----(backbone0.0)---- | -------(backbone0.1)------ 48 | | | 49 BR1 ............. BR2 ........ BR3 50 51 """ 52 USE_MESSAGE_FACTORY = False 53 BR1, BR2, BR3 = range(1, 4) 54 55 TOPOLOGY = { 56 BR1: { 57 'name': 'BR_1', 58 'backbone_network_id': 0, 59 'allowlist': [BR2], 60 'is_otbr': True, 61 'version': '1.4', 62 }, 63 BR2: { 64 'name': 'BR_2', 65 'backbone_network_id': 1, 66 'allowlist': [BR1, BR3], 67 'is_otbr': True, 68 'version': '1.4', 69 }, 70 BR3: { 71 'name': 'BR_3', 72 'backbone_network_id': 1, 73 'allowlist': [BR2], 74 'is_otbr': True, 75 'version': '1.4', 76 } 77 } 78 79 def test_multi_backbone_infra(self): 80 """This test ensures that the multiple backbone infra works as expected.""" 81 br1: OtbrNode = self.nodes[self.BR1] 82 br2: OtbrNode = self.nodes[self.BR2] 83 br3: OtbrNode = self.nodes[self.BR3] 84 85 # start nodes 86 for br in [br1, br2, br3]: 87 br.start() 88 self.simulator.go(config.BORDER_ROUTER_STARTUP_DELAY) 89 90 # check BR1 and BR2 are not on the same subnet, but BR2 and BR3 are on the same subnet 91 br1_infra_ip_addr = br1.bash(IPV4_CIDR_ADDR_CMD) 92 br2_infra_ip_addr = br2.bash(IPV4_CIDR_ADDR_CMD) 93 br3_infra_ip_addr = br3.bash(IPV4_CIDR_ADDR_CMD) 94 assert len(br1_infra_ip_addr) == 1 95 assert len(br2_infra_ip_addr) == 1 96 assert len(br3_infra_ip_addr) == 1 97 98 self.assertNotEqual(ipaddress.ip_network(br1_infra_ip_addr[0].strip(), strict=False), 99 ipaddress.ip_network(br2_infra_ip_addr[0].strip(), strict=False)) 100 self.assertEqual(ipaddress.ip_network(br2_infra_ip_addr[0].strip(), strict=False), 101 ipaddress.ip_network(br3_infra_ip_addr[0].strip(), strict=False)) 102 103 # ping each other using Thread MLEID 104 br1_mleid = br1.get_ip6_address(config.ADDRESS_TYPE.ML_EID) 105 br2_mleid = br2.get_ip6_address(config.ADDRESS_TYPE.ML_EID) 106 br3_mleid = br3.get_ip6_address(config.ADDRESS_TYPE.ML_EID) 107 108 self.assertTrue(br1.ping(br2_mleid)) 109 self.assertTrue(br1.ping(br3_mleid)) 110 self.assertTrue(br2.ping(br1_mleid)) 111 self.assertTrue(br2.ping(br3_mleid)) 112 self.assertTrue(br3.ping(br1_mleid)) 113 self.assertTrue(br3.ping(br2_mleid)) 114 115 # ping each other using Infra ULA 116 br1_onlink_ula = br1.get_ip6_address(config.ADDRESS_TYPE.ONLINK_ULA)[0] 117 br2_onlink_ula = br2.get_ip6_address(config.ADDRESS_TYPE.ONLINK_ULA)[0] 118 br3_onlink_ula = br3.get_ip6_address(config.ADDRESS_TYPE.ONLINK_ULA)[0] 119 120 self.assertFalse(br1.ping(br2_onlink_ula, backbone=True)) 121 self.assertFalse(br1.ping(br3_onlink_ula, backbone=True)) 122 self.assertFalse(br2.ping(br1_onlink_ula, backbone=True)) 123 self.assertFalse(br3.ping(br1_onlink_ula, backbone=True)) 124 self.assertTrue(br2.ping(br3_onlink_ula, backbone=True)) 125 self.assertTrue(br3.ping(br2_onlink_ula, backbone=True)) 126 127 128if __name__ == '__main__': 129 unittest.main(verbosity=2) 130