1#!/usr/bin/env python3 2# 3# Copyright (c) 2021, 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# 29import unittest 30 31import config 32import thread_cert 33 34# Test description: 35# This test verifies TREL connectivity. 36# 37# Topology: 38# ----------------(eth)-------------------------- 39# | | 40# FED1 --- BR1 (Leader) ----- BR2 --- ROUTER2 41# /\ 42# / \ 43# MED1 SED1 44# 45from config import PACKET_VERIFICATION_TREL 46from pktverify.packet_filter import PacketFilter 47from pktverify.packet_verifier import PacketVerifier 48 49BR1 = 1 50FED1 = 2 51MED1 = 3 52SED1 = 4 53BR2 = 5 54ROUTER2 = 6 55 56 57class TestTrelConnectivity(thread_cert.TestCase): 58 USE_MESSAGE_FACTORY = False 59 PACKET_VERIFICATION = PACKET_VERIFICATION_TREL 60 61 TOPOLOGY = { 62 BR1: { 63 'name': 'BR1', 64 'allowlist': [BR2, FED1, MED1, SED1], 65 'is_otbr': True, 66 'version': '1.2', 67 }, 68 FED1: { 69 'name': 'ROUTER1', 70 'allowlist': [BR1], 71 'version': '1.2', 72 'router_eligible': False, 73 }, 74 MED1: { 75 'name': 'MED1', 76 'allowlist': [BR1], 77 'version': '1.2', 78 'mode': 'rn', 79 }, 80 SED1: { 81 'name': 'SED1', 82 'allowlist': [BR1], 83 'version': '1.2', 84 'mode': 'n', 85 }, 86 BR2: { 87 'name': 'BR2', 88 'allowlist': [BR1, ROUTER2], 89 'is_otbr': True, 90 'version': '1.2', 91 }, 92 ROUTER2: { 93 'name': 'ROUTER2', 94 'allowlist': [BR2], 95 'version': '1.2', 96 }, 97 } 98 99 def test(self): 100 br1 = self.nodes[BR1] 101 fed1 = self.nodes[FED1] 102 med1 = self.nodes[MED1] 103 sed1 = self.nodes[SED1] 104 br2 = self.nodes[BR2] 105 router2 = self.nodes[ROUTER2] 106 107 if br1.is_trel_enabled() is None: 108 self.skipTest("TREL is not supported") 109 110 if br1.is_trel_enabled() == False: 111 br1.enable_trel() 112 113 if br2.is_trel_enabled() == False: 114 br2.enable_trel() 115 116 br1.start() 117 self.wait_node_state(br1, 'leader', 10) 118 119 fed1.start() 120 self.wait_node_state(fed1, 'child', 10) 121 122 med1.start() 123 self.wait_node_state(med1, 'child', 10) 124 125 sed1.start() 126 self.wait_node_state(sed1, 'child', 10) 127 128 br2.start() 129 self.wait_node_state(br2, 'router', 10) 130 131 router2.start() 132 self.wait_node_state(router2, 'router', 10) 133 134 # Allow the network to stabilize 135 self.simulator.go(config.BORDER_ROUTER_STARTUP_DELAY) 136 137 self.collect_ipaddrs() 138 self.collect_rloc16s() 139 140 router2_mleid = router2.get_mleid() 141 self.assertTrue(br1.ping(router2_mleid)) 142 self.assertTrue(fed1.ping(router2_mleid)) 143 self.assertTrue(med1.ping(router2_mleid)) 144 self.assertTrue(sed1.ping(router2_mleid)) 145 146 counters = br1.get_trel_counters() 147 print('br1 trel counters', counters) 148 self.assertTrue(counters['Inbound']['packets'] > 0) 149 self.assertTrue(counters['Inbound']['bytes'] > 0) 150 self.assertTrue(counters['Outbound']['packets'] > 0) 151 self.assertTrue(counters['Outbound']['bytes'] > 0) 152 self.assertTrue(counters['Outbound']['failures'] >= 0) 153 154 br1.reset_trel_counters() 155 counters = br1.get_trel_counters() 156 print('br1 trel counters after reset', counters) 157 self.assertTrue(counters['Inbound']['packets'] == 0) 158 self.assertTrue(counters['Inbound']['bytes'] == 0) 159 self.assertTrue(counters['Outbound']['packets'] == 0) 160 self.assertTrue(counters['Outbound']['bytes'] == 0) 161 self.assertTrue(counters['Outbound']['failures'] == 0) 162 163 def verify(self, pv: PacketVerifier): 164 pkts: PacketFilter = pv.pkts 165 BR1_RLOC16 = pv.vars['BR1_RLOC16'] 166 BR2_RLOC16 = pv.vars['BR2_RLOC16'] 167 168 print('BR1_RLOC16:', hex(BR1_RLOC16)) 169 print('BR2_RLOC16:', hex(BR2_RLOC16)) 170 171 # Make sure BR1 and BR2 always use TREL for transmitting ping request and reply 172 pkts.filter_wpan_src16_dst16(BR1_RLOC16, BR2_RLOC16).filter_ping_request().must_not_next() 173 pkts.filter_wpan_src16_dst16(BR1_RLOC16, BR2_RLOC16).filter_ping_reply().must_not_next() 174 175 pkts.filter_wpan_src16_dst16(BR2_RLOC16, BR1_RLOC16).filter_ping_request().must_not_next() 176 pkts.filter_wpan_src16_dst16(BR2_RLOC16, BR1_RLOC16).filter_ping_reply().must_not_next() 177 178 179if __name__ == '__main__': 180 unittest.main() 181