summaryrefslogtreecommitdiffstats
path: root/test/test_npt66.py
diff options
context:
space:
mode:
authorOle Troan <otroan@employees.org>2023-08-17 13:36:08 +0200
committerOle Troan <otroan@employees.org>2023-08-25 09:15:32 +0200
commit6ee3aa41c395d036c8c79a3681cc5ee6bc6fceb9 (patch)
treefcbb367a65e0c9fc932f62fcaf2d46ff622ba9dc /test/test_npt66.py
parentecb62d2e5d0af14e2de143a729abdf35e132e5d5 (diff)
npt66: network prefix translation for ipv6
This is the initial commit of a NPTv6 (RFC6296) implementation for VPP. It's restricted to a single internal to external binding and runs as an output/input feature on the egress interface. Type: feature Change-Id: I0e3497af97f1ebd99377b84dbf599ecea935ca24 Signed-off-by: Ole Troan <otroan@employees.org>
Diffstat (limited to 'test/test_npt66.py')
-rw-r--r--test/test_npt66.py89
1 files changed, 89 insertions, 0 deletions
diff --git a/test/test_npt66.py b/test/test_npt66.py
new file mode 100644
index 00000000000..5173c62d44f
--- /dev/null
+++ b/test/test_npt66.py
@@ -0,0 +1,89 @@
+#!/usr/bin/env python3
+
+import unittest
+import ipaddress
+from framework import VppTestCase, VppTestRunner
+
+from scapy.layers.inet6 import IPv6, ICMPv6EchoRequest
+from scapy.layers.l2 import Ether
+from scapy.packet import Raw
+
+
+class TestNPT66(VppTestCase):
+ """NPTv6 Test Case"""
+
+ def setUp(self):
+ super(TestNPT66, self).setUp()
+
+ # create 2 pg interfaces
+ self.create_pg_interfaces(range(2))
+
+ for i in self.pg_interfaces:
+ i.admin_up()
+ i.config_ip6()
+ i.resolve_ndp()
+
+ def tearDown(self):
+ for i in self.pg_interfaces:
+ i.unconfig_ip6()
+ i.admin_down()
+ super(TestNPT66, self).tearDown()
+
+ def send_and_verify(self, in2out, internal, external):
+ if in2out:
+ sendif = self.pg0
+ recvif = self.pg1
+ local_mac = self.pg0.local_mac
+ remote_mac = self.pg0.remote_mac
+ src = ipaddress.ip_interface(internal).ip + 1
+ dst = self.pg1.remote_ip6
+ else:
+ sendif = self.pg1
+ recvif = self.pg0
+ local_mac = self.pg1.local_mac
+ remote_mac = self.pg1.remote_mac
+ src = self.pg1.remote_ip6
+ dst = ipaddress.ip_interface(external).ip + 1
+
+ p = (
+ Ether(dst=local_mac, src=remote_mac)
+ / IPv6(src=src, dst=dst)
+ / ICMPv6EchoRequest()
+ )
+ rxs = self.send_and_expect(sendif, p, recvif)
+ for rx in rxs:
+ rx.show2()
+ original_cksum = rx[ICMPv6EchoRequest].cksum
+ del rx[ICMPv6EchoRequest].cksum
+ rx = rx.__class__(bytes(rx))
+ self.assertEqual(original_cksum, rx[ICMPv6EchoRequest].cksum)
+
+ def do_test(self, internal, external):
+ self.vapi.npt66_binding_add_del(
+ sw_if_index=self.pg1.sw_if_index,
+ internal=internal,
+ external=external,
+ is_add=True,
+ )
+ self.vapi.cli(f"ip route add {internal} via {self.pg0.remote_ip6}")
+
+ self.send_and_verify(True, internal, external)
+ self.send_and_verify(False, internal, external)
+
+ self.vapi.npt66_binding_add_del(
+ sw_if_index=self.pg1.sw_if_index,
+ internal=internal,
+ external=external,
+ is_add=False,
+ )
+
+ def test_npt66_simple(self):
+ """Send and receive a packet through NPT66"""
+
+ self.do_test("fc00:1::/48", "2001:db8:1::/48")
+ self.do_test("fc00:1234::/32", "2001:db8:1::/32")
+ self.do_test("fc00:1234::/63", "2001:db8:1::/56")
+
+
+if __name__ == "__main__":
+ unittest.main(testRunner=VppTestRunner)