ipsec: add ipv6 support for ipsec tunnel interface

Change-Id: I6a76907dc7bed2a81282b63669bea2219d6903c9
Signed-off-by: Kingwel Xie <kingwel.xie@ericsson.com>
Signed-off-by: Neale Ranns <neale.ranns@cisco.com>
diff --git a/test/template_ipsec.py b/test/template_ipsec.py
index 68f1183..483699c 100644
--- a/test/template_ipsec.py
+++ b/test/template_ipsec.py
@@ -477,14 +477,15 @@
             self.logger.info(self.vapi.ppcli("show error"))
             self.logger.info(self.vapi.ppcli("show ipsec"))
 
-        pkts = p.tun_sa_in.get_stats()['packets']
-        self.assertEqual(pkts, count,
-                         "incorrect SA in counts: expected %d != %d" %
-                         (count, pkts))
-        pkts = p.tun_sa_out.get_stats()['packets']
-        self.assertEqual(pkts, count,
-                         "incorrect SA out counts: expected %d != %d" %
-                         (count, pkts))
+        if (hasattr(p, "tun_sa_in")):
+            pkts = p.tun_sa_in.get_stats()['packets']
+            self.assertEqual(pkts, count,
+                             "incorrect SA in counts: expected %d != %d" %
+                             (count, pkts))
+            pkts = p.tun_sa_out.get_stats()['packets']
+            self.assertEqual(pkts, count,
+                             "incorrect SA out counts: expected %d != %d" %
+                             (count, pkts))
         self.assert_packet_counter_equal(self.tun6_encrypt_node_name, count)
         self.assert_packet_counter_equal(self.tun6_decrypt_node_name, count)
 
diff --git a/test/test_ipsec_tun_if_esp.py b/test/test_ipsec_tun_if_esp.py
index 2734908..06d2c89 100644
--- a/test/test_ipsec_tun_if_esp.py
+++ b/test/test_ipsec_tun_if_esp.py
@@ -2,18 +2,19 @@
 import socket
 from scapy.layers.ipsec import ESP
 from framework import VppTestRunner
-from template_ipsec import TemplateIpsec, IpsecTun4Tests, IpsecTcpTests
+from template_ipsec import TemplateIpsec, IpsecTun4Tests, IpsecTun6Tests, \
+    IpsecTcpTests
 from vpp_ipsec_tun_interface import VppIpsecTunInterface
-from vpp_ip_route import VppIpRoute, VppRoutePath
+from vpp_ip_route import VppIpRoute, VppRoutePath, DpoProto
 
 
-class TemplateIpsecTunIfEsp(TemplateIpsec):
+class TemplateIpsec4TunIfEsp(TemplateIpsec):
     """ IPsec tunnel interface tests """
 
     encryption_type = ESP
 
     def setUp(self):
-        super(TemplateIpsecTunIfEsp, self).setUp()
+        super(TemplateIpsec4TunIfEsp, self).setUp()
 
         self.tun_if = self.pg0
 
@@ -34,19 +35,57 @@
     def tearDown(self):
         if not self.vpp_dead:
             self.vapi.cli("show hardware")
-        super(TemplateIpsecTunIfEsp, self).tearDown()
+        super(TemplateIpsec4TunIfEsp, self).tearDown()
 
 
-class TestIpsecTunIfEsp1(TemplateIpsecTunIfEsp, IpsecTun4Tests):
+class TestIpsec4TunIfEsp1(TemplateIpsec4TunIfEsp, IpsecTun4Tests):
     """ Ipsec ESP - TUN tests """
     tun4_encrypt_node_name = "esp4-encrypt"
     tun4_decrypt_node_name = "esp4-decrypt"
 
 
-class TestIpsecTunIfEsp2(TemplateIpsecTunIfEsp, IpsecTcpTests):
+class TestIpsec4TunIfEsp2(TemplateIpsec4TunIfEsp, IpsecTcpTests):
     """ Ipsec ESP - TCP tests """
     pass
 
 
+class TemplateIpsec6TunIfEsp(TemplateIpsec):
+    """ IPsec tunnel interface tests """
+
+    encryption_type = ESP
+
+    def setUp(self):
+        super(TemplateIpsec6TunIfEsp, self).setUp()
+
+        self.tun_if = self.pg0
+
+        p = self.ipv6_params
+        tun_if = VppIpsecTunInterface(self, self.pg0, p.vpp_tun_spi,
+                                      p.scapy_tun_spi, p.crypt_algo_vpp_id,
+                                      p.crypt_key, p.crypt_key,
+                                      p.auth_algo_vpp_id, p.auth_key,
+                                      p.auth_key, is_ip6=True)
+        tun_if.add_vpp_config()
+        tun_if.admin_up()
+        tun_if.config_ip6()
+
+        VppIpRoute(self,  p.remote_tun_if_host, 32,
+                   [VppRoutePath(tun_if.remote_ip6,
+                                 0xffffffff,
+                                 proto=DpoProto.DPO_PROTO_IP6)],
+                   is_ip6=1).add_vpp_config()
+
+    def tearDown(self):
+        if not self.vpp_dead:
+            self.vapi.cli("show hardware")
+        super(TemplateIpsec6TunIfEsp, self).tearDown()
+
+
+class TestIpsec6TunIfEsp1(TemplateIpsec6TunIfEsp, IpsecTun6Tests):
+    """ Ipsec ESP - TUN tests """
+    tun6_encrypt_node_name = "esp6-encrypt"
+    tun6_decrypt_node_name = "esp6-decrypt"
+
+
 if __name__ == '__main__':
     unittest.main(testRunner=VppTestRunner)
diff --git a/test/vpp_ipsec_tun_interface.py b/test/vpp_ipsec_tun_interface.py
index bd63541..5c014ea 100644
--- a/test/vpp_ipsec_tun_interface.py
+++ b/test/vpp_ipsec_tun_interface.py
@@ -8,7 +8,7 @@
 
     def __init__(self, test, parent_if, local_spi,
                  remote_spi, crypto_alg, local_crypto_key, remote_crypto_key,
-                 integ_alg, local_integ_key, remote_integ_key):
+                 integ_alg, local_integ_key, remote_integ_key, is_ip6=False):
         super(VppIpsecTunInterface, self).__init__(test, parent_if)
         self.local_spi = local_spi
         self.remote_spi = remote_spi
@@ -18,23 +18,30 @@
         self.integ_alg = integ_alg
         self.local_integ_key = local_integ_key
         self.remote_integ_key = remote_integ_key
+        if is_ip6:
+            self.local_ip = self.parent_if.local_ip6
+            self.remote_ip = self.parent_if.remote_ip6
+        else:
+            self.local_ip = self.parent_if.local_ip4
+            self.remote_ip = self.parent_if.remote_ip4
 
     def add_vpp_config(self):
         r = self.test.vapi.ipsec_tunnel_if_add_del(
-            self.parent_if.local_ip4n, self.parent_if.remote_ip4n,
-            self.remote_spi, self.local_spi, self.crypto_alg,
-            self.local_crypto_key, self.remote_crypto_key, self.integ_alg,
-            self.local_integ_key, self.remote_integ_key)
+            self.local_ip, self.remote_ip,
+            self.remote_spi, self.local_spi,
+            self.crypto_alg, self.local_crypto_key, self.remote_crypto_key,
+            self.integ_alg, self.local_integ_key, self.remote_integ_key)
         self.set_sw_if_index(r.sw_if_index)
         self.generate_remote_hosts()
         self.test.registry.register(self, self.test.logger)
 
     def remove_vpp_config(self):
         self.test.vapi.ipsec_tunnel_if_add_del(
-            self.parent_if.local_ip4n, self.parent_if.remote_ip4n,
-            self.remote_spi, self.local_spi, self.crypto_alg,
-            self.local_crypto_key, self.remote_crypto_key, self.integ_alg,
-            self.local_integ_key, self.remote_integ_key, is_add=0)
+            self.local_ip, self.remote_ip,
+            self.remote_spi, self.local_spi,
+            self.crypto_alg, self.local_crypto_key, self.remote_crypto_key,
+            self.integ_alg, self.local_integ_key, self.remote_integ_key,
+            is_add=0)
 
     def __str__(self):
         return self.object_id()
diff --git a/test/vpp_papi_provider.py b/test/vpp_papi_provider.py
index 9133683..d393ce1 100644
--- a/test/vpp_papi_provider.py
+++ b/test/vpp_papi_provider.py
@@ -2485,20 +2485,27 @@
                                 anti_replay=1, renumber=0, show_instance=0):
         return self.api(
             self.papi.ipsec_tunnel_if_add_del,
-            {'local_ip': local_ip, 'remote_ip': remote_ip,
-             'local_spi': local_spi, 'remote_spi': remote_spi,
-             'crypto_alg': crypto_alg,
-             'local_crypto_key_len': len(local_crypto_key),
-             'local_crypto_key': local_crypto_key,
-             'remote_crypto_key_len': len(remote_crypto_key),
-             'remote_crypto_key': remote_crypto_key, 'integ_alg': integ_alg,
-             'local_integ_key_len': len(local_integ_key),
-             'local_integ_key': local_integ_key,
-             'remote_integ_key_len': len(remote_integ_key),
-             'remote_integ_key': remote_integ_key, 'is_add': is_add,
-             'esn': esn, 'anti_replay': anti_replay, 'renumber': renumber,
-             'show_instance': show_instance
-             })
+            {
+                'local_ip': local_ip,
+                'remote_ip': remote_ip,
+                'local_spi': local_spi,
+                'remote_spi': remote_spi,
+                'crypto_alg': crypto_alg,
+                'local_crypto_key_len': len(local_crypto_key),
+                'local_crypto_key': local_crypto_key,
+                'remote_crypto_key_len': len(remote_crypto_key),
+                'remote_crypto_key': remote_crypto_key,
+                'integ_alg': integ_alg,
+                'local_integ_key_len': len(local_integ_key),
+                'local_integ_key': local_integ_key,
+                'remote_integ_key_len': len(remote_integ_key),
+                'remote_integ_key': remote_integ_key,
+                'is_add': is_add,
+                'esn': esn,
+                'anti_replay': anti_replay,
+                'renumber': renumber,
+                'show_instance': show_instance
+            })
 
     def ipsec_select_backend(self, protocol, index):
         return self.api(self.papi.ipsec_select_backend,