LISP statistics
[vpp.git] / test / test_snat.py
index 4cb5116..7084f00 100644 (file)
@@ -405,7 +405,7 @@ class TestSNAT(VppTestCase):
             proto,
             is_add)
 
-    def snat_add_address(self, ip, is_add=1):
+    def snat_add_address(self, ip, is_add=1, vrf_id=0xFFFFFFFF):
         """
         Add/delete S-NAT address
 
@@ -413,7 +413,8 @@ class TestSNAT(VppTestCase):
         :param is_add: 1 if add, 0 if delete (Default add)
         """
         snat_addr = socket.inet_pton(socket.AF_INET, ip)
-        self.vapi.snat_add_address_range(snat_addr, snat_addr, is_add)
+        self.vapi.snat_add_address_range(snat_addr, snat_addr, is_add,
+                                         vrf_id=vrf_id)
 
     def test_dynamic(self):
         """ SNAT dynamic translation test """
@@ -1201,6 +1202,73 @@ class TestSNAT(VppTestCase):
         self.pg_start()
         capture = self.pg1.get_capture(0)
 
+    def test_vrf_mode(self):
+        """ S-NAT tenant VRF aware address pool mode """
+
+        vrf_id1 = 1
+        vrf_id2 = 2
+        nat_ip1 = "10.0.0.10"
+        nat_ip2 = "10.0.0.11"
+
+        self.pg0.unconfig_ip4()
+        self.pg1.unconfig_ip4()
+        self.pg0.set_table_ip4(vrf_id1)
+        self.pg1.set_table_ip4(vrf_id2)
+        self.pg0.config_ip4()
+        self.pg1.config_ip4()
+
+        self.snat_add_address(nat_ip1, vrf_id=vrf_id1)
+        self.snat_add_address(nat_ip2, vrf_id=vrf_id2)
+        self.vapi.snat_interface_add_del_feature(self.pg0.sw_if_index)
+        self.vapi.snat_interface_add_del_feature(self.pg1.sw_if_index)
+        self.vapi.snat_interface_add_del_feature(self.pg2.sw_if_index,
+                                                 is_inside=0)
+
+        # first VRF
+        pkts = self.create_stream_in(self.pg0, self.pg2)
+        self.pg0.add_stream(pkts)
+        self.pg_enable_capture(self.pg_interfaces)
+        self.pg_start()
+        capture = self.pg2.get_capture(len(pkts))
+        self.verify_capture_out(capture, nat_ip1)
+
+        # second VRF
+        pkts = self.create_stream_in(self.pg1, self.pg2)
+        self.pg1.add_stream(pkts)
+        self.pg_enable_capture(self.pg_interfaces)
+        self.pg_start()
+        capture = self.pg2.get_capture(len(pkts))
+        self.verify_capture_out(capture, nat_ip2)
+
+    def test_vrf_feature_independent(self):
+        """ S-NAT tenant VRF independent address pool mode """
+
+        nat_ip1 = "10.0.0.10"
+        nat_ip2 = "10.0.0.11"
+
+        self.snat_add_address(nat_ip1)
+        self.snat_add_address(nat_ip2)
+        self.vapi.snat_interface_add_del_feature(self.pg0.sw_if_index)
+        self.vapi.snat_interface_add_del_feature(self.pg1.sw_if_index)
+        self.vapi.snat_interface_add_del_feature(self.pg2.sw_if_index,
+                                                 is_inside=0)
+
+        # first VRF
+        pkts = self.create_stream_in(self.pg0, self.pg2)
+        self.pg0.add_stream(pkts)
+        self.pg_enable_capture(self.pg_interfaces)
+        self.pg_start()
+        capture = self.pg2.get_capture(len(pkts))
+        self.verify_capture_out(capture, nat_ip1)
+
+        # second VRF
+        pkts = self.create_stream_in(self.pg1, self.pg2)
+        self.pg1.add_stream(pkts)
+        self.pg_enable_capture(self.pg_interfaces)
+        self.pg_start()
+        capture = self.pg2.get_capture(len(pkts))
+        self.verify_capture_out(capture, nat_ip1)
+
     def tearDown(self):
         super(TestSNAT, self).tearDown()
         if not self.vpp_dead:
@@ -1208,5 +1276,77 @@ class TestSNAT(VppTestCase):
             self.clear_snat()
 
 
+class TestDeterministicNAT(VppTestCase):
+    """ Deterministic NAT Test Cases """
+
+    @classmethod
+    def setUpConstants(cls):
+        super(TestDeterministicNAT, cls).setUpConstants()
+        cls.vpp_cmdline.extend(["snat", "{", "deterministic", "}"])
+
+    @classmethod
+    def setUpClass(cls):
+        super(TestDeterministicNAT, cls).setUpClass()
+
+        try:
+            cls.create_pg_interfaces(range(2))
+            cls.interfaces = list(cls.pg_interfaces)
+
+            for i in cls.interfaces:
+                i.admin_up()
+                i.config_ip4()
+                i.resolve_arp()
+
+        except Exception:
+            super(TestDeterministicNAT, cls).tearDownClass()
+            raise
+
+    def test_deterministic_mode(self):
+        """ S-NAT run deterministic mode """
+        in_addr = '172.16.255.0'
+        out_addr = '172.17.255.50'
+        in_addr_t = '172.16.255.20'
+        in_addr_n = socket.inet_aton(in_addr)
+        out_addr_n = socket.inet_aton(out_addr)
+        in_addr_t_n = socket.inet_aton(in_addr_t)
+        in_plen = 24
+        out_plen = 32
+
+        snat_config = self.vapi.snat_show_config()
+        self.assertEqual(1, snat_config.deterministic)
+
+        self.vapi.snat_add_det_map(in_addr_n, in_plen, out_addr_n, out_plen)
+
+        rep1 = self.vapi.snat_det_forward(in_addr_t_n)
+        self.assertEqual(rep1.out_addr[:4], out_addr_n)
+        rep2 = self.vapi.snat_det_reverse(out_addr_n, rep1.out_port_hi)
+        self.assertEqual(rep2.in_addr[:4], in_addr_t_n)
+
+        deterministic_mappings = self.vapi.snat_det_map_dump()
+        self.assertEqual(len(deterministic_mappings), 1)
+        dsm = deterministic_mappings[0]
+        self.assertEqual(in_addr_n, dsm.in_addr[:4])
+        self.assertEqual(in_plen, dsm.in_plen)
+        self.assertEqual(out_addr_n, dsm.out_addr[:4])
+        self.assertEqual(out_plen, dsm.out_plen)
+
+    def clear_snat(self):
+        """
+        Clear SNAT configuration.
+        """
+        deterministic_mappings = self.vapi.snat_det_map_dump()
+        for dsm in deterministic_mappings:
+            self.vapi.snat_add_det_map(dsm.in_addr,
+                                       dsm.in_plen,
+                                       dsm.out_addr,
+                                       dsm.out_plen,
+                                       is_add=0)
+
+    def tearDown(self):
+        super(TestDeterministicNAT, self).tearDown()
+        if not self.vpp_dead:
+            self.logger.info(self.vapi.cli("show snat detail"))
+            self.clear_snat()
+
 if __name__ == '__main__':
     unittest.main(testRunner=VppTestRunner)