mirror of
https://github.com/espressif/openthread.git
synced 2026-09-09 10:40:09 +00:00
[nat64] NAT64 translator should be active only when local prefix is published (#8558)
If an infrastructure-provided NAT64 prefix is present, we should bypass the NAT64 translator to let the border router forward the packet to the infra NAT64 service.
This commit is contained in:
@@ -26,7 +26,6 @@
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
#
|
||||
from typing import Mapping
|
||||
import unittest
|
||||
|
||||
import config
|
||||
@@ -85,19 +84,6 @@ class Nat64MultiBorderRouter(thread_cert.TestCase):
|
||||
},
|
||||
}
|
||||
|
||||
def assertDictIncludes(self, actual: Mapping[str, str], expected: Mapping[str, str]):
|
||||
""" Asserts the `actual` dict includes the `expected` dict.
|
||||
|
||||
Args:
|
||||
actual: A dict for checking.
|
||||
expected: The expected items that the actual dict should contains.
|
||||
"""
|
||||
for k, v in expected.items():
|
||||
if k not in actual:
|
||||
raise AssertionError(f"key {k} is not found in first dict")
|
||||
if v != actual[k]:
|
||||
raise AssertionError(f"{repr(actual[k])} != {repr(v)} for key {k}")
|
||||
|
||||
def test(self):
|
||||
br1 = self.nodes[BR1]
|
||||
router = self.nodes[ROUTER]
|
||||
@@ -123,6 +109,7 @@ class Nat64MultiBorderRouter(thread_cert.TestCase):
|
||||
#
|
||||
# Case 1. BR2 with an infrastructure prefix joins the network later and
|
||||
# it will add the infrastructure nat64 prefix to Network Data.
|
||||
# Note: NAT64 translator will be bypassed.
|
||||
#
|
||||
br2.start()
|
||||
# When feature flag is enabled, NAT64 might be disabled by default. So
|
||||
@@ -146,7 +133,7 @@ class Nat64MultiBorderRouter(thread_cert.TestCase):
|
||||
})
|
||||
self.assertDictIncludes(br2.nat64_state, {
|
||||
'PrefixManager': NAT64_STATE_ACTIVE,
|
||||
'Translator': NAT64_STATE_ACTIVE
|
||||
'Translator': NAT64_STATE_NOT_RUNNING
|
||||
})
|
||||
|
||||
#
|
||||
|
||||
@@ -52,6 +52,11 @@ SMALL_NAT64_PREFIX = "2000:0:0:1:0:0::/96"
|
||||
|
||||
NAT64_PREFIX_REFRESH_DELAY = 305
|
||||
|
||||
NAT64_STATE_DISABLED = 'disabled'
|
||||
NAT64_STATE_NOT_RUNNING = 'not_running'
|
||||
NAT64_STATE_IDLE = 'idle'
|
||||
NAT64_STATE_ACTIVE = 'active'
|
||||
|
||||
|
||||
class Nat64SingleBorderRouter(thread_cert.TestCase):
|
||||
USE_MESSAGE_FACTORY = False
|
||||
@@ -91,6 +96,10 @@ class Nat64SingleBorderRouter(thread_cert.TestCase):
|
||||
self.assertEqual(len(br.get_netdata_nat64_prefix()), 1)
|
||||
nat64_prefix = br.get_netdata_nat64_prefix()[0]
|
||||
self.assertEqual(nat64_prefix, infra_nat64_prefix)
|
||||
self.assertDictIncludes(br.nat64_state, {
|
||||
'PrefixManager': NAT64_STATE_ACTIVE,
|
||||
'Translator': NAT64_STATE_NOT_RUNNING
|
||||
})
|
||||
|
||||
# Case 2 Withdraw infrastructure prefix when a smaller prefix in medium
|
||||
# preference is present
|
||||
@@ -100,6 +109,10 @@ class Nat64SingleBorderRouter(thread_cert.TestCase):
|
||||
|
||||
self.assertEqual(len(br.get_netdata_nat64_prefix()), 1)
|
||||
self.assertNotEqual(infra_nat64_prefix, br.get_netdata_nat64_prefix()[0])
|
||||
self.assertDictIncludes(br.nat64_state, {
|
||||
'PrefixManager': NAT64_STATE_IDLE,
|
||||
'Translator': NAT64_STATE_NOT_RUNNING
|
||||
})
|
||||
|
||||
br.remove_route(SMALL_NAT64_PREFIX)
|
||||
br.register_netdata()
|
||||
@@ -115,6 +128,10 @@ class Nat64SingleBorderRouter(thread_cert.TestCase):
|
||||
|
||||
self.assertEqual(len(br.get_netdata_nat64_prefix()), 2)
|
||||
self.assertEqual(br.get_netdata_nat64_prefix(), [infra_nat64_prefix, SMALL_NAT64_PREFIX])
|
||||
self.assertDictIncludes(br.nat64_state, {
|
||||
'PrefixManager': NAT64_STATE_ACTIVE,
|
||||
'Translator': NAT64_STATE_NOT_RUNNING
|
||||
})
|
||||
|
||||
br.remove_route(SMALL_NAT64_PREFIX)
|
||||
br.register_netdata()
|
||||
@@ -128,6 +145,10 @@ class Nat64SingleBorderRouter(thread_cert.TestCase):
|
||||
self.assertNotEqual(local_nat64_prefix, infra_nat64_prefix)
|
||||
self.assertEqual(len(br.get_netdata_nat64_prefix()), 1)
|
||||
self.assertEqual(br.get_netdata_nat64_prefix()[0], local_nat64_prefix)
|
||||
self.assertDictIncludes(br.nat64_state, {
|
||||
'PrefixManager': NAT64_STATE_ACTIVE,
|
||||
'Translator': NAT64_STATE_ACTIVE
|
||||
})
|
||||
|
||||
# Case 5 Infrastructure nat64 prefix is recovered
|
||||
br.bash("service bind9 start")
|
||||
@@ -136,6 +157,10 @@ class Nat64SingleBorderRouter(thread_cert.TestCase):
|
||||
self.assertEqual(br.get_br_favored_nat64_prefix(), infra_nat64_prefix)
|
||||
self.assertEqual(len(br.get_netdata_nat64_prefix()), 1)
|
||||
self.assertEqual(br.get_netdata_nat64_prefix()[0], infra_nat64_prefix)
|
||||
self.assertDictIncludes(br.nat64_state, {
|
||||
'PrefixManager': NAT64_STATE_ACTIVE,
|
||||
'Translator': NAT64_STATE_NOT_RUNNING
|
||||
})
|
||||
|
||||
# Case 6 Change infrastructure nat64 prefix
|
||||
br.bash("sed -i 's/dns64 /\/\/dns64 /' /etc/bind/named.conf.options")
|
||||
@@ -146,6 +171,10 @@ class Nat64SingleBorderRouter(thread_cert.TestCase):
|
||||
self.assertEqual(br.get_br_favored_nat64_prefix(), SMALL_NAT64_PREFIX)
|
||||
self.assertEqual(len(br.get_netdata_nat64_prefix()), 1)
|
||||
self.assertEqual(br.get_netdata_nat64_prefix()[0], SMALL_NAT64_PREFIX)
|
||||
self.assertDictIncludes(br.nat64_state, {
|
||||
'PrefixManager': NAT64_STATE_ACTIVE,
|
||||
'Translator': NAT64_STATE_NOT_RUNNING
|
||||
})
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
@@ -38,7 +38,7 @@ import sys
|
||||
import time
|
||||
import traceback
|
||||
import unittest
|
||||
from typing import Optional, Callable, Union, Any
|
||||
from typing import Optional, Callable, Union, Mapping, Any
|
||||
|
||||
import config
|
||||
import debug
|
||||
@@ -592,3 +592,16 @@ class TestCase(NcpSupportMixin, unittest.TestCase):
|
||||
|
||||
else:
|
||||
raise Exception("Route between node %d and %d is not established" % (node1, node2))
|
||||
|
||||
def assertDictIncludes(self, actual: Mapping[str, str], expected: Mapping[str, str]):
|
||||
""" Asserts the `actual` dict includes the `expected` dict.
|
||||
|
||||
Args:
|
||||
actual: A dict for checking.
|
||||
expected: The expected items that the actual dict should contains.
|
||||
"""
|
||||
for k, v in expected.items():
|
||||
if k not in actual:
|
||||
raise AssertionError(f"key {k} is not found in first dict")
|
||||
if v != actual[k]:
|
||||
raise AssertionError(f"{repr(actual[k])} != {repr(v)} for key {k}")
|
||||
|
||||
Reference in New Issue
Block a user