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 29from cli import verify 30from cli import verify_within 31import cli 32import time 33 34# ----------------------------------------------------------------------------------------------------------------------- 35# Test description: 36# 37# BR sending ICMPv6 Unreachable error. 38# 39# - - - AIL- - - 40# | | 41# BR1 BR2 42# | 43# router2 44# 45 46test_name = __file__[:-3] if __file__.endswith('.py') else __file__ 47print('-' * 120) 48print('Starting \'{}\''.format(test_name)) 49 50# ----------------------------------------------------------------------------------------------------------------------- 51# Creating `cli.Nodes` instances 52 53speedup = 20 54cli.Node.set_time_speedup_factor(speedup) 55 56br1 = cli.Node() 57br2 = cli.Node() 58router2 = cli.Node() 59 60IF_INDEX = 1 61 62# ----------------------------------------------------------------------------------------------------------------------- 63# Test implementation 64 65# Start `br1` on its own Thread network with a custom OMR 66# prefix and a custom on-link prefix. Both prefixes are 67# non-ULA. 68 69br1.form('net1') 70verify(br1.get_state() == 'leader') 71 72br1.add_prefix('1000::/64', 'paors') 73br1.register_netdata() 74 75br1.br_init(IF_INDEX, 1) 76br1.br_enable() 77 78br1.br_set_test_local_onlinkprefix('2000::/64') 79 80time.sleep(2) 81verify(br1.br_get_state() == 'running') 82 83br1_local_onlink = br1.br_get_local_onlinkprefix() 84br1_favored_onlink = br1.br_get_favored_onlinkprefix().split()[0] 85verify(br1_local_onlink == br1_favored_onlink) 86verify(br1_local_onlink == '2000:0:0:0::/64') 87 88br1_local_omr = br1.br_get_local_omrprefix() 89br1_favored_omr = br1.br_get_favored_omrprefix().split()[0] 90verify(br1_favored_omr == '1000:0:0:0::/64') 91 92#- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 93# Start `br2` on its own Thread network. 94 95br2.form('net2') 96router2.join(br2) 97verify(br2.get_state() == 'leader') 98verify(router2.get_state() == 'router') 99 100br2.br_init(IF_INDEX, 1) 101br2.br_enable() 102 103time.sleep(2) 104verify(br2.br_get_state() == 'running') 105 106br2_local_omr = br2.br_get_local_omrprefix() 107br2_favored_omr = br2.br_get_favored_omrprefix().split()[0] 108verify(br2_local_omr == br2_favored_omr) 109 110br2_local_onlink = br2.br_get_local_onlinkprefix() 111br2_favored_onlink = br2.br_get_favored_onlinkprefix().split()[0] 112verify(br2_local_onlink != br2_favored_onlink) 113verify(br2_favored_onlink == '2000:0:0:0::/64') 114 115#- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 116# Validate that the `br2` published '::/0' route due to 117# discovery of a non-ULA on-link prefix. 118 119for node in [br2, router2]: 120 routes = node.get_netdata_routes() 121 verify(len(routes) == 1) 122 verify(routes[0].startswith('::/0 s')) 123 124#- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 125# Send a ping from `router2` to an AIL address (derived from the 126# advertised on-link prefix). Verify that, BR2 receives and 127# forwards the message, and BR2 does not send an ICMPv6 error, as 128# the destination is within the AIL. 129 130router2.ping('2000::1', verify_success=False) 131 132verify(br2.get_br_counter_unicast_outbound_packets() == 1) 133 134rx_history = router2.cli('history rx list') 135verify(len(rx_history) == 0) 136 137#- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 138# Send a ping from `router2` to an address on BR1 mesh network 139# (derived from its OMR prefix). Verify that again it is 140# received and forwarded by BR2 and again no ICMPv6 error is 141# sent. 142 143router2.ping('1000::1', verify_success=False) 144 145verify(br2.get_br_counter_unicast_outbound_packets() == 2) 146 147rx_history = router2.cli('history rx list') 148verify(len(rx_history) == 0) 149 150#- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 151# Send a ping to an outside AIL address, make sure BR2 152# does receive and forward it and now also sends an ICMPv6 153# error 154 155router2.ping('3000::', verify_success=False) 156 157verify(br2.get_br_counter_unicast_outbound_packets() == 3) 158 159rx_history = router2.cli('history rx list') 160verify(rx_history[1].strip().startswith('type:ICMP6(Unreach)')) 161 162# ----------------------------------------------------------------------------------------------------------------------- 163# Test finished 164 165cli.Node.finalize_all_nodes() 166 167print('\'{}\' passed.'.format(test_name)) 168