• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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#
29
30import unittest
31
32import config
33import thread_cert
34
35# Test description:
36#
37#   This test verifies the behavior of the network when a zero length external route prefix "::/0" is added.
38#
39# Topology:
40#
41#    leader --- router1
42#       \         /
43#        \       /
44#         router2
45#
46
47LEADER = 1
48ROUTER1 = 2
49ROUTER2 = 3
50
51
52class ZeroLengthExternalRoute(thread_cert.TestCase):
53    USE_MESSAGE_FACTORY = False
54    SUPPORT_NCP = False
55
56    TOPOLOGY = {
57        LEADER: {
58            'name': 'LEADER',
59            'mode': 'rdn',
60        },
61        ROUTER1: {
62            'name': 'ROUTER2',
63            'mode': 'rdn',
64        },
65        ROUTER2: {
66            'name': 'ROUTER2',
67            'mode': 'rdn',
68        },
69    }
70
71    def test(self):
72        leader = self.nodes[LEADER]
73        router1 = self.nodes[ROUTER1]
74        router2 = self.nodes[ROUTER2]
75
76        # Start the nodes and form the network.
77
78        leader.start()
79        self.simulator.go(config.LEADER_STARTUP_DELAY)
80        self.assertEqual(leader.get_state(), 'leader')
81
82        router1.start()
83        router2.start()
84        self.simulator.go(config.ROUTER_STARTUP_DELAY)
85        self.assertEqual(router1.get_state(), 'router')
86        self.assertEqual(router2.get_state(), 'router')
87
88        # Add an on-mesh prefix with SLAAC on router2 (without default
89        # route flag).
90
91        router2.add_prefix('fd00:1234::/64', 'paos')
92        router2.register_netdata()
93
94        # Add a zero length external route on router1. Also add an IPv6
95        # address on router1.
96
97        router1.add_route('::/0', stable=True)
98        router1.add_ipaddr('fd00:abcd::1')
99        router1.register_netdata()
100        self.simulator.go(5)
101
102        # Ping from leader the address added on router1. The zero
103        # length external route should ensure the message is routed
104        # to router1.
105
106        self.assertTrue(leader.ping('fd00:abcd::1'))
107
108        # Change the on-mesh prefix on router2 to now also have
109        # the default route flag.
110
111        router2.remove_prefix('fd00:1234::/64')
112        router2.add_prefix('fd00:5678::/64', 'paros')
113        router2.register_netdata()
114        self.simulator.go(5)
115
116        # Again ping from leader the same address. The explicit
117        # external route (even with zero length) on router1 should
118        # still be preferred over the default route flag of the
119        # on-mesh prefix from router2.
120
121        self.assertTrue(leader.ping('fd00:abcd::1'))
122
123        # Remove the external route on router1.
124
125        router1.remove_route("::/0")
126        router1.register_netdata()
127        self.simulator.go(5)
128
129        # Now the ping should fail since the message would be routed
130        # to router2 (due to its on-mesh prefix with default route
131        # flag).
132
133        self.assertFalse(leader.ping('fd00:abcd::1'))
134
135        # Remove the address from router1 and add it on router2 and
136        # ping it again from leader to verify that the message is
137        # being routed to router2.
138
139        router1.del_ipaddr('fd00:abcd::1')
140        router2.add_ipaddr('fd00:abcd::1')
141        self.simulator.go(5)
142        self.assertTrue(leader.ping('fd00:abcd::1'))
143
144
145if __name__ == '__main__':
146    unittest.main()
147