ipsec: add missing ipv6 ah code & ipv6 tests 69/15069/6
authorKlement Sekera <ksekera@cisco.com>
Wed, 26 Sep 2018 09:19:00 +0000 (11:19 +0200)
committerDamjan Marion <dmarion@me.com>
Wed, 3 Oct 2018 17:38:41 +0000 (17:38 +0000)
Change-Id: I89e90193ded1beb6cb0950c15737f9467efac1c3
Signed-off-by: Klement Sekera <ksekera@cisco.com>
13 files changed:
src/vnet/ipsec/ah.h
src/vnet/ipsec/ah_decrypt.c
src/vnet/ipsec/ah_encrypt.c
src/vnet/ipsec/ipsec_input.c
test/framework.py
test/template_ipsec.py
test/test_ipsec_ah.py
test/test_ipsec_esp.py
test/test_ipsec_nat.py
test/test_ipsec_tun_if_esp.py
test/util.py
test/vpp_interface.py
test/vpp_papi_provider.py

index 37fc29a..f74ad9b 100644 (file)
@@ -49,6 +49,15 @@ typedef CLIB_PACKED (struct {
 }) ip6_and_ah_header_t;
 /* *INDENT-ON* */
 
+always_inline u8
+ah_calc_icv_padding_len (u8 icv_size, int is_ipv6)
+{
+  ASSERT (0 == is_ipv6 || 1 == is_ipv6);
+  const u8 req_multiple = 4 + 4 * is_ipv6;     // 4 for ipv4, 8 for ipv6
+  const u8 total_size = sizeof (ah_header_t) + icv_size;
+  return (req_multiple - total_size % req_multiple) % req_multiple;
+}
+
 #endif /* __AH_H__ */
 
 /*
index c487d82..abe2e6f 100644 (file)
@@ -112,6 +112,10 @@ ah_decrypt_node_fn (vlib_main_t * vm,
          u8 ip_hdr_size = 0;
          u8 tos = 0;
          u8 ttl = 0;
+         u32 ip_version_traffic_class_and_flow_label = 0;
+         u8 hop_limit = 0;
+         u8 nexthdr = 0;
+         u8 icv_padding_len = 0;
 
 
          i_bi0 = from[0];
@@ -125,12 +129,29 @@ ah_decrypt_node_fn (vlib_main_t * vm,
          to_next[0] = i_bi0;
          to_next += 1;
          ih4 = vlib_buffer_get_current (i_b0);
-         ip_hdr_size = ip4_header_bytes (ih4);
-         ah0 = (ah_header_t *) ((u8 *) ih4 + ip_hdr_size);
-
+         ih6 = vlib_buffer_get_current (i_b0);
          sa_index0 = vnet_buffer (i_b0)->ipsec.sad_index;
          sa0 = pool_elt_at_index (im->sad, sa_index0);
 
+         if ((ih4->ip_version_and_header_length & 0xF0) == 0x40)
+           {
+             ip_hdr_size = ip4_header_bytes (ih4);
+             ah0 = (ah_header_t *) ((u8 *) ih4 + ip_hdr_size);
+           }
+         else if ((ih4->ip_version_and_header_length & 0xF0) == 0x60)
+           {
+             ip6_ext_header_t *prev = NULL;
+             ip6_ext_header_find_t (ih6, prev, ah0, IP_PROTOCOL_IPSEC_AH);
+             ip_hdr_size = sizeof (ip6_header_t);
+             ASSERT ((u8 *) ah0 - (u8 *) ih6 == ip_hdr_size);
+           }
+         else
+           {
+             vlib_node_increment_counter (vm, ah_decrypt_node.index,
+                                          AH_DECRYPT_ERROR_NOT_IP, 1);
+             goto trace;
+           }
+
          seq = clib_host_to_net_u32 (ah0->seq_no);
          /* anti-replay check */
          //TODO UT remaining
@@ -164,9 +185,7 @@ ah_decrypt_node_fn (vlib_main_t * vm,
              u8 digest[64];
              memset (sig, 0, sizeof (sig));
              memset (digest, 0, sizeof (digest));
-             u8 *icv =
-               vlib_buffer_get_current (i_b0) + ip_hdr_size +
-               sizeof (ah_header_t);
+             u8 *icv = ah0->auth_data;
              memcpy (digest, icv, icv_size);
              memset (icv, 0, icv_size);
 
@@ -178,7 +197,20 @@ ah_decrypt_node_fn (vlib_main_t * vm,
                  ih4->ttl = 0;
                  ih4->checksum = 0;
                  ih4->flags_and_fragment_offset = 0;
-               }               //TODO else part for IPv6
+                 icv_padding_len =
+                   ah_calc_icv_padding_len (icv_size, 0 /* is_ipv6 */ );
+               }
+             else
+               {
+                 ip_version_traffic_class_and_flow_label =
+                   ih6->ip_version_traffic_class_and_flow_label;
+                 hop_limit = ih6->hop_limit;
+                 ih6->ip_version_traffic_class_and_flow_label = 0x60;
+                 ih6->hop_limit = 0;
+                 nexthdr = ah0->nexthdr;
+                 icv_padding_len =
+                   ah_calc_icv_padding_len (icv_size, 1 /* is_ipv6 */ );
+               }
              hmac_calc (sa0->integ_alg, sa0->integ_key, sa0->integ_key_len,
                         (u8 *) ih4, i_b0->current_length, sig, sa0->use_esn,
                         sa0->seq_hi);
@@ -204,9 +236,9 @@ ah_decrypt_node_fn (vlib_main_t * vm,
 
            }
 
-
          vlib_buffer_advance (i_b0,
-                              ip_hdr_size + sizeof (ah_header_t) + icv_size);
+                              ip_hdr_size + sizeof (ah_header_t) + icv_size +
+                              icv_padding_len);
          i_b0->flags |= VLIB_BUFFER_TOTAL_LENGTH_VALID;
 
          /* transport mode */
@@ -251,15 +283,15 @@ ah_decrypt_node_fn (vlib_main_t * vm,
            {
              if (PREDICT_FALSE (transport_ip6))
                {
-                 ih6 =
-                   (ip6_header_t *) (i_b0->data +
-                                     sizeof (ethernet_header_t));
                  vlib_buffer_advance (i_b0, -sizeof (ip6_header_t));
                  oh6 = vlib_buffer_get_current (i_b0);
                  memmove (oh6, ih6, sizeof (ip6_header_t));
 
                  next0 = AH_DECRYPT_NEXT_IP6_INPUT;
-                 oh6->protocol = ah0->nexthdr;
+                 oh6->protocol = nexthdr;
+                 oh6->hop_limit = hop_limit;
+                 oh6->ip_version_traffic_class_and_flow_label =
+                   ip_version_traffic_class_and_flow_label;
                  oh6->payload_length =
                    clib_host_to_net_u16 (vlib_buffer_length_in_chain
                                          (vm, i_b0) - sizeof (ip6_header_t));
index 898c0f2..911dd33 100644 (file)
@@ -110,6 +110,8 @@ ah_encrypt_node_fn (vlib_main_t * vm,
          u8 transport_mode = 0;
          u8 tos = 0;
          u8 ttl = 0;
+         u8 hop_limit = 0;
+         u32 ip_version_traffic_class_and_flow_label = 0;
 
          i_bi0 = from[0];
          from += 1;
@@ -159,6 +161,8 @@ ah_encrypt_node_fn (vlib_main_t * vm,
 
          icv_size =
            em->ipsec_proto_main_integ_algs[sa0->integ_alg].trunc_size;
+         const u8 padding_len = ah_calc_icv_padding_len (icv_size, is_ipv6);
+         adv -= padding_len;
          /*transport mode save the eth header before it is overwritten */
          if (PREDICT_FALSE (!sa0->is_tunnel))
            {
@@ -172,18 +176,18 @@ ah_encrypt_node_fn (vlib_main_t * vm,
 
          vlib_buffer_advance (i_b0, adv - icv_size);
 
-         /* is ipv6 */
          if (PREDICT_FALSE (is_ipv6))
-           {
+           {                   /* is ipv6 */
              ih6_0 = (ip6_and_ah_header_t *) ih0;
              ip_hdr_size = sizeof (ip6_header_t);
              oh6_0 = vlib_buffer_get_current (i_b0);
 
+             hop_limit = ih6_0->ip6.hop_limit;
+             ip_version_traffic_class_and_flow_label =
+               ih6_0->ip6.ip_version_traffic_class_and_flow_label;
              if (PREDICT_TRUE (sa0->is_tunnel))
                {
                  next_hdr_type = IP_PROTOCOL_IPV6;
-                 oh6_0->ip6.ip_version_traffic_class_and_flow_label =
-                   ih6_0->ip6.ip_version_traffic_class_and_flow_label;
                }
              else
                {
@@ -192,12 +196,17 @@ ah_encrypt_node_fn (vlib_main_t * vm,
                }
 
              oh6_0->ip6.protocol = IP_PROTOCOL_IPSEC_AH;
-             oh6_0->ip6.hop_limit = 254;
+             oh6_0->ip6.hop_limit = 0;
+             oh6_0->ip6.ip_version_traffic_class_and_flow_label = 0x60;
+             oh6_0->ah.reserved = 0;
+             oh6_0->ah.nexthdr = next_hdr_type;
              oh6_0->ah.spi = clib_net_to_host_u32 (sa0->spi);
              oh6_0->ah.seq_no = clib_net_to_host_u32 (sa0->seq);
              oh6_0->ip6.payload_length =
                clib_host_to_net_u16 (vlib_buffer_length_in_chain (vm, i_b0) -
                                      sizeof (ip6_header_t));
+             oh6_0->ah.hdrlen =
+               (sizeof (ah_header_t) + icv_size + padding_len) / 4 - 2;
            }
          else
            {
@@ -227,11 +236,11 @@ ah_encrypt_node_fn (vlib_main_t * vm,
              oh0->ah.seq_no = clib_net_to_host_u32 (sa0->seq);
              oh0->ip4.checksum = 0;
              oh0->ah.nexthdr = next_hdr_type;
-             oh0->ah.hdrlen = 4;
+             oh0->ah.hdrlen =
+               (sizeof (ah_header_t) + icv_size + padding_len) / 4 - 2;
            }
 
 
-
          if (PREDICT_TRUE
              (!is_ipv6 && sa0->is_tunnel && !sa0->is_tunnel_ip6))
            {
@@ -264,7 +273,8 @@ ah_encrypt_node_fn (vlib_main_t * vm,
          u8 sig[64];
          memset (sig, 0, sizeof (sig));
          u8 *digest =
-           vlib_buffer_get_current (i_b0) + ip_hdr_size + icv_size;
+           vlib_buffer_get_current (i_b0) + ip_hdr_size +
+           sizeof (ah_header_t);
          memset (digest, 0, icv_size);
 
          unsigned size = hmac_calc (sa0->integ_alg, sa0->integ_key,
@@ -276,6 +286,9 @@ ah_encrypt_node_fn (vlib_main_t * vm,
          memcpy (digest, sig, size);
          if (PREDICT_FALSE (is_ipv6))
            {
+             oh6_0->ip6.hop_limit = hop_limit;
+             oh6_0->ip6.ip_version_traffic_class_and_flow_label =
+               ip_version_traffic_class_and_flow_label;
            }
          else
            {
index b7bb07b..ebfb909 100644 (file)
@@ -348,13 +348,13 @@ VLIB_REGISTER_NODE (ipsec_input_ip4_node,static) = {
 };
 /* *INDENT-ON* */
 
-VLIB_NODE_FUNCTION_MULTIARCH (ipsec_input_ip4_node, ipsec_input_ip4_node_fn)
-     static vlib_node_registration_t ipsec_input_ip6_node;
+VLIB_NODE_FUNCTION_MULTIARCH (ipsec_input_ip4_node, ipsec_input_ip4_node_fn);
+static vlib_node_registration_t ipsec_input_ip6_node;
 
-     static uword
-       ipsec_input_ip6_node_fn (vlib_main_t * vm,
-                               vlib_node_runtime_t * node,
-                               vlib_frame_t * from_frame)
+static uword
+ipsec_input_ip6_node_fn (vlib_main_t * vm,
+                        vlib_node_runtime_t * node,
+                        vlib_frame_t * from_frame)
 {
   u32 n_left_from, *from, next_index, *to_next;
   ipsec_main_t *im = &ipsec_main;
@@ -379,6 +379,7 @@ VLIB_NODE_FUNCTION_MULTIARCH (ipsec_input_ip4_node, ipsec_input_ip4_node_fn)
          ip4_ipsec_config_t *c0;
          ipsec_spd_t *spd0;
          ipsec_policy_t *p0 = 0;
+         ah_header_t *ah0;
          u32 header_size = sizeof (ip0[0]);
 
          bi0 = to_next[0] = from[0];
@@ -396,6 +397,7 @@ VLIB_NODE_FUNCTION_MULTIARCH (ipsec_input_ip4_node, ipsec_input_ip4_node_fn)
 
          ip0 = vlib_buffer_get_current (b0);
          esp0 = (esp_header_t *) ((u8 *) ip0 + header_size);
+         ah0 = (ah_header_t *) ((u8 *) ip0 + header_size);
 
          if (PREDICT_TRUE (ip0->protocol == IP_PROTOCOL_IPSEC_ESP))
            {
@@ -426,6 +428,26 @@ VLIB_NODE_FUNCTION_MULTIARCH (ipsec_input_ip4_node, ipsec_input_ip4_node_fn)
                  goto trace0;
                }
            }
+         else if (ip0->protocol == IP_PROTOCOL_IPSEC_AH)
+           {
+             p0 = ipsec_input_ip6_protect_policy_match (spd0,
+                                                        &ip0->src_address,
+                                                        &ip0->dst_address,
+                                                        clib_net_to_host_u32
+                                                        (ah0->spi));
+
+             if (PREDICT_TRUE (p0 != 0))
+               {
+                 p0->counter.packets++;
+                 p0->counter.bytes +=
+                   clib_net_to_host_u16 (ip0->payload_length);
+                 p0->counter.bytes += header_size;
+                 vnet_buffer (b0)->ipsec.sad_index = p0->sa_index;
+                 vnet_buffer (b0)->ipsec.flags = 0;
+                 next0 = im->ah_decrypt_next_index;
+                 goto trace0;
+               }
+           }
 
        trace0:
          if (PREDICT_FALSE (b0->flags & VLIB_BUFFER_IS_TRACED))
index cd15aec..da34724 100644 (file)
@@ -287,8 +287,7 @@ class VppTestCase(unittest.TestCase):
                            coredump_size, "}", "api-trace", "{", "on", "}",
                            "api-segment", "{", "prefix", cls.shm_prefix, "}",
                            "cpu", "{", "main-core", str(cpu_core_number), "}",
-                           "statseg", "{", "socket-name",
-                           cls.tempdir + "/stats.sock", "}",
+                           "statseg", "{", "socket-name", cls.stats_sock, "}",
                            "plugins", "{", "plugin", "dpdk_plugin.so", "{",
                            "disable", "}", "plugin", "unittest_plugin.so",
                            "{", "enable", "}", "}", ]
@@ -346,6 +345,13 @@ class VppTestCase(unittest.TestCase):
 
         cls.wait_for_enter()
 
+    @classmethod
+    def wait_for_stats_socket(cls):
+        deadline = time.time() + 3
+        while time.time() < deadline or cls.debug_gdb or cls.debug_gdbserver:
+            if os.path.exists(cls.stats_sock):
+                break
+
     @classmethod
     def setUpClass(cls):
         """
@@ -360,6 +366,7 @@ class VppTestCase(unittest.TestCase):
             cls.logger.name = cls.__name__
         cls.tempdir = tempfile.mkdtemp(
             prefix='vpp-unittest-%s-' % cls.__name__)
+        cls.stats_sock = "%s/stats.sock" % cls.tempdir
         cls.file_handler = FileHandler("%s/log.txt" % cls.tempdir)
         cls.file_handler.setFormatter(
             Formatter(fmt='%(asctime)s,%(msecs)03d %(message)s',
@@ -391,14 +398,19 @@ class VppTestCase(unittest.TestCase):
             cls.pump_thread = Thread(target=pump_output, args=(cls,))
             cls.pump_thread.daemon = True
             cls.pump_thread.start()
-            cls.vapi = VppPapiProvider(cls.shm_prefix, cls.shm_prefix, cls)
+            if cls.debug_gdb or cls.debug_gdbserver:
+                read_timeout = 0
+            else:
+                read_timeout = 5
+            cls.vapi = VppPapiProvider(cls.shm_prefix, cls.shm_prefix, cls,
+                                       read_timeout)
             if cls.step:
                 hook = StepHook(cls)
             else:
                 hook = PollHook(cls)
             cls.vapi.register_hook(hook)
-            cls.sleep(0.1, "after vpp startup, before initial poll")
-            cls.statistics = VPPStats(socketname=cls.tempdir+'/stats.sock')
+            cls.wait_for_stats_socket()
+            cls.statistics = VPPStats(socketname=cls.stats_sock)
             try:
                 hook.poll_vpp()
             except VppDiedError:
@@ -459,7 +471,7 @@ class VppTestCase(unittest.TestCase):
             cls.vpp.poll()
             if cls.vpp.returncode is None:
                 cls.logger.debug("Sending TERM to vpp")
-                cls.vpp.terminate()
+                cls.vpp.kill()
                 cls.logger.debug("Waiting for vpp to die")
                 cls.vpp.communicate()
             del cls.vpp
index 9d95185..bf13d71 100644 (file)
@@ -1,13 +1,69 @@
 import unittest
+import socket
 
 from scapy.layers.inet import IP, ICMP, TCP
 from scapy.layers.ipsec import SecurityAssociation
 from scapy.layers.l2 import Ether, Raw
+from scapy.layers.inet6 import IPv6, ICMPv6EchoRequest
 
 from framework import VppTestCase, VppTestRunner
 from util import ppp
 
 
+class IPsecIPv4Params(object):
+    addr_type = socket.AF_INET
+    addr_any = "0.0.0.0"
+    addr_bcast = "255.255.255.255"
+    addr_len = 32
+    is_ipv6 = 0
+    remote_tun_if_host = '1.1.1.1'
+
+    scapy_tun_sa_id = 10
+    scapy_tun_spi = 1001
+    vpp_tun_sa_id = 20
+    vpp_tun_spi = 1000
+
+    scapy_tra_sa_id = 30
+    scapy_tra_spi = 2001
+    vpp_tra_sa_id = 40
+    vpp_tra_spi = 2000
+
+    auth_algo_vpp_id = 2  # internal VPP enum value for SHA1_96
+    auth_algo = 'HMAC-SHA1-96'  # scapy name
+    auth_key = 'C91KUR9GYMm5GfkEvNjX'
+
+    crypt_algo_vpp_id = 1  # internal VPP enum value for AES_CBC_128
+    crypt_algo = 'AES-CBC'  # scapy name
+    crypt_key = 'JPjyOWBeVEQiMe7h'
+
+
+class IPsecIPv6Params(object):
+    addr_type = socket.AF_INET6
+    addr_any = "0::0"
+    addr_bcast = "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"
+    addr_len = 128
+    is_ipv6 = 1
+    remote_tun_if_host = '1111:1111:1111:1111:1111:1111:1111:1111'
+
+    scapy_tun_sa_id = 50
+    scapy_tun_spi = 3001
+    vpp_tun_sa_id = 60
+    vpp_tun_spi = 3000
+
+    scapy_tra_sa_id = 70
+    scapy_tra_spi = 4001
+    vpp_tra_sa_id = 80
+    vpp_tra_spi = 4000
+
+    auth_algo_vpp_id = 4  # internal VPP enum value for SHA_256_128
+    auth_algo = 'SHA2-256-128'  # scapy name
+    auth_key = 'C91KUR9GYMm5GfkEvNjX'
+
+    crypt_algo_vpp_id = 3  # internal VPP enum value for AES_CBC_256
+    crypt_algo = 'AES-CBC'  # scapy name
+    crypt_key = 'JPjyOWBeVEQiMe7hJPjyOWBeVEQiMe7h'
+
+
 class TemplateIpsec(VppTestCase):
     """
     TRANSPORT MODE:
@@ -26,33 +82,19 @@ class TemplateIpsec(VppTestCase):
     |tun_if| ------->  |VPP| ------> |pg1|
      ------             ---           ---
     """
+    ipv4_params = IPsecIPv4Params()
+    ipv6_params = IPsecIPv6Params()
+    params = {ipv4_params.addr_type: ipv4_params,
+              ipv6_params.addr_type: ipv6_params}
 
-    remote_tun_if_host = '1.1.1.1'
     payload = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
 
     tun_spd_id = 1
-    scapy_tun_sa_id = 10
-    scapy_tun_spi = 1001
-    vpp_tun_sa_id = 20
-    vpp_tun_spi = 1000
-
     tra_spd_id = 2
-    scapy_tra_sa_id = 30
-    scapy_tra_spi = 2001
-    vpp_tra_sa_id = 40
-    vpp_tra_spi = 2000
 
     vpp_esp_protocol = 1
     vpp_ah_protocol = 0
 
-    auth_algo_vpp_id = 2  # internal VPP enum value for SHA1_96
-    auth_algo = 'HMAC-SHA1-96'  # scapy name
-    auth_key = 'C91KUR9GYMm5GfkEvNjX'
-
-    crypt_algo_vpp_id = 1  # internal VPP enum value for AES_CBC_128
-    crypt_algo = 'AES-CBC'  # scapy name
-    crypt_key = 'JPjyOWBeVEQiMe7h'
-
     @classmethod
     def setUpClass(cls):
         super(TemplateIpsec, cls).setUpClass()
@@ -62,63 +104,67 @@ class TemplateIpsec(VppTestCase):
             i.admin_up()
             i.config_ip4()
             i.resolve_arp()
+            i.config_ip6()
+            i.resolve_ndp()
 
     def tearDown(self):
         super(TemplateIpsec, self).tearDown()
         if not self.vpp_dead:
             self.vapi.cli("show hardware")
 
-    def send_and_expect(self, input, pkts, output, count=1):
-        input.add_stream(pkts)
-        self.pg_enable_capture(self.pg_interfaces)
-        self.pg_start()
-        rx = output.get_capture(count)
-        return rx
-
     def gen_encrypt_pkts(self, sa, sw_intf, src, dst, count=1):
         return [Ether(src=sw_intf.remote_mac, dst=sw_intf.local_mac) /
                 sa.encrypt(IP(src=src, dst=dst) / ICMP() / self.payload)
                 for i in range(count)]
 
+    def gen_encrypt_pkts6(self, sa, sw_intf, src, dst, count=1):
+        return [Ether(src=sw_intf.remote_mac, dst=sw_intf.local_mac) /
+                sa.encrypt(IPv6(src=src, dst=dst) /
+                           ICMPv6EchoRequest(id=0, seq=1, data=self.payload))
+                for i in range(count)]
+
     def gen_pkts(self, sw_intf, src, dst, count=1):
         return [Ether(src=sw_intf.remote_mac, dst=sw_intf.local_mac) /
                 IP(src=src, dst=dst) / ICMP() / self.payload
                 for i in range(count)]
 
-    def configure_sa_tun(self):
-        scapy_tun_sa = SecurityAssociation(self.encryption_type,
-                                           spi=self.vpp_tun_spi,
-                                           crypt_algo=self.crypt_algo,
-                                           crypt_key=self.crypt_key,
-                                           auth_algo=self.auth_algo,
-                                           auth_key=self.auth_key,
-                                           tunnel_header=IP(
-                                               src=self.tun_if.remote_ip4,
-                                               dst=self.tun_if.local_ip4))
-        vpp_tun_sa = SecurityAssociation(self.encryption_type,
-                                         spi=self.scapy_tun_spi,
-                                         crypt_algo=self.crypt_algo,
-                                         crypt_key=self.crypt_key,
-                                         auth_algo=self.auth_algo,
-                                         auth_key=self.auth_key,
-                                         tunnel_header=IP(
-                                             dst=self.tun_if.remote_ip4,
-                                             src=self.tun_if.local_ip4))
+    def gen_pkts6(self, sw_intf, src, dst, count=1):
+        return [Ether(src=sw_intf.remote_mac, dst=sw_intf.local_mac) /
+                IPv6(src=src, dst=dst) /
+                ICMPv6EchoRequest(id=0, seq=1, data=self.payload)
+                for i in range(count)]
+
+    def configure_sa_tun(self, params):
+        ip_class_by_addr_type = {socket.AF_INET: IP, socket.AF_INET6: IPv6}
+        scapy_tun_sa = SecurityAssociation(
+            self.encryption_type, spi=params.vpp_tun_spi,
+            crypt_algo=params.crypt_algo, crypt_key=params.crypt_key,
+            auth_algo=params.auth_algo, auth_key=params.auth_key,
+            tunnel_header=ip_class_by_addr_type[params.addr_type](
+                src=self.tun_if.remote_addr[params.addr_type],
+                dst=self.tun_if.local_addr[params.addr_type]))
+        vpp_tun_sa = SecurityAssociation(
+            self.encryption_type, spi=params.scapy_tun_spi,
+            crypt_algo=params.crypt_algo, crypt_key=params.crypt_key,
+            auth_algo=params.auth_algo, auth_key=params.auth_key,
+            tunnel_header=ip_class_by_addr_type[params.addr_type](
+                dst=self.tun_if.remote_addr[params.addr_type],
+                src=self.tun_if.local_addr[params.addr_type]))
         return vpp_tun_sa, scapy_tun_sa
 
-    def configure_sa_tra(self):
+    def configure_sa_tra(self, params):
         scapy_tra_sa = SecurityAssociation(self.encryption_type,
-                                           spi=self.vpp_tra_spi,
-                                           crypt_algo=self.crypt_algo,
-                                           crypt_key=self.crypt_key,
-                                           auth_algo=self.auth_algo,
-                                           auth_key=self.auth_key)
+                                           spi=params.vpp_tra_spi,
+                                           crypt_algo=params.crypt_algo,
+                                           crypt_key=params.crypt_key,
+                                           auth_algo=params.auth_algo,
+                                           auth_key=params.auth_key)
         vpp_tra_sa = SecurityAssociation(self.encryption_type,
-                                         spi=self.scapy_tra_spi,
-                                         crypt_algo=self.crypt_algo,
-                                         crypt_key=self.crypt_key,
-                                         auth_algo=self.auth_algo,
-                                         auth_key=self.auth_key)
+                                         spi=params.scapy_tra_spi,
+                                         crypt_algo=params.crypt_algo,
+                                         crypt_key=params.crypt_key,
+                                         auth_algo=params.auth_algo,
+                                         auth_key=params.auth_key)
         return vpp_tra_sa, scapy_tra_sa
 
 
@@ -126,13 +172,14 @@ class IpsecTcpTests(object):
     def test_tcp_checksum(self):
         """ verify checksum correctness for vpp generated packets """
         self.vapi.cli("test http server")
-        vpp_tun_sa, scapy_tun_sa = self.configure_sa_tun()
+        p = self.params[socket.AF_INET]
+        vpp_tun_sa, scapy_tun_sa = self.configure_sa_tun(p)
         send = (Ether(src=self.tun_if.remote_mac, dst=self.tun_if.local_mac) /
-                scapy_tun_sa.encrypt(IP(src=self.remote_tun_if_host,
+                scapy_tun_sa.encrypt(IP(src=p.remote_tun_if_host,
                                         dst=self.tun_if.local_ip4) /
                                      TCP(flags='S', dport=80)))
         self.logger.debug(ppp("Sending packet:", send))
-        recv = self.send_and_expect(self.tun_if, [send], self.tun_if, 1)
+        recv = self.send_and_expect(self.tun_if, [send], self.tun_if)
         recv = recv[0]
         decrypted = vpp_tun_sa.decrypt(recv[IP])
         self.assert_packet_checksums_valid(decrypted)
@@ -142,67 +189,146 @@ class IpsecTraTests(object):
     def test_tra_basic(self, count=1):
         """ ipsec v4 transport basic test """
         try:
-            vpp_tra_sa, scapy_tra_sa = self.configure_sa_tra()
+            p = self.params[socket.AF_INET]
+            vpp_tra_sa, scapy_tra_sa = self.configure_sa_tra(p)
             send_pkts = self.gen_encrypt_pkts(scapy_tra_sa, self.tra_if,
                                               src=self.tra_if.remote_ip4,
                                               dst=self.tra_if.local_ip4,
                                               count=count)
             recv_pkts = self.send_and_expect(self.tra_if, send_pkts,
-                                             self.tra_if, count=count)
+                                             self.tra_if)
             for p in recv_pkts:
-                decrypted = vpp_tra_sa.decrypt(p[IP])
-                self.assert_packet_checksums_valid(decrypted)
+                try:
+                    decrypted = vpp_tra_sa.decrypt(p[IP])
+                    self.assert_packet_checksums_valid(decrypted)
+                except:
+                    self.logger.debug(ppp("Unexpected packet:", p))
+                    raise
         finally:
             self.logger.info(self.vapi.ppcli("show error"))
             self.logger.info(self.vapi.ppcli("show ipsec"))
 
     def test_tra_burst(self):
         """ ipsec v4 transport burst test """
+        self.test_tra_basic(count=257)
+
+    def test_tra_basic6(self, count=1):
+        """ ipsec v6 transport basic test """
         try:
-            self.test_tra_basic(count=257)
+            p = self.params[socket.AF_INET6]
+            vpp_tra_sa, scapy_tra_sa = self.configure_sa_tra(p)
+            send_pkts = self.gen_encrypt_pkts6(scapy_tra_sa, self.tra_if,
+                                               src=self.tra_if.remote_ip6,
+                                               dst=self.tra_if.local_ip6,
+                                               count=count)
+            recv_pkts = self.send_and_expect(self.tra_if, send_pkts,
+                                             self.tra_if)
+            for p in recv_pkts:
+                try:
+                    decrypted = vpp_tra_sa.decrypt(p[IPv6])
+                    self.assert_packet_checksums_valid(decrypted)
+                except:
+                    self.logger.debug(ppp("Unexpected packet:", p))
+                    raise
         finally:
             self.logger.info(self.vapi.ppcli("show error"))
             self.logger.info(self.vapi.ppcli("show ipsec"))
 
+    def test_tra_burst6(self):
+        """ ipsec v6 transport burst test """
+        self.test_tra_basic6(count=257)
+
 
-class IpsecTunTests(object):
-    def test_tun_basic(self, count=1):
+class IpsecTun4Tests(object):
+    def test_tun_basic44(self, count=1):
         """ ipsec 4o4 tunnel basic test """
         try:
-            vpp_tun_sa, scapy_tun_sa = self.configure_sa_tun()
+            p = self.params[socket.AF_INET]
+            vpp_tun_sa, scapy_tun_sa = self.configure_sa_tun(p)
             send_pkts = self.gen_encrypt_pkts(scapy_tun_sa, self.tun_if,
-                                              src=self.remote_tun_if_host,
+                                              src=p.remote_tun_if_host,
                                               dst=self.pg1.remote_ip4,
                                               count=count)
-            recv_pkts = self.send_and_expect(self.tun_if, send_pkts, self.pg1,
-                                             count=count)
+            recv_pkts = self.send_and_expect(self.tun_if, send_pkts, self.pg1)
             for recv_pkt in recv_pkts:
-                self.assert_equal(recv_pkt[IP].src, self.remote_tun_if_host)
+                self.assert_equal(recv_pkt[IP].src, p.remote_tun_if_host)
                 self.assert_equal(recv_pkt[IP].dst, self.pg1.remote_ip4)
                 self.assert_packet_checksums_valid(recv_pkt)
             send_pkts = self.gen_pkts(self.pg1, src=self.pg1.remote_ip4,
-                                      dst=self.remote_tun_if_host, count=count)
-            recv_pkts = self.send_and_expect(self.pg1, send_pkts, self.tun_if,
-                                             count=count)
+                                      dst=p.remote_tun_if_host, count=count)
+            recv_pkts = self.send_and_expect(self.pg1, send_pkts, self.tun_if)
             for recv_pkt in recv_pkts:
-                decrypt_pkt = vpp_tun_sa.decrypt(recv_pkt[IP])
-                if not decrypt_pkt.haslayer(IP):
-                    decrypt_pkt = IP(decrypt_pkt[Raw].load)
-                self.assert_equal(decrypt_pkt.src, self.pg1.remote_ip4)
-                self.assert_equal(decrypt_pkt.dst, self.remote_tun_if_host)
-                self.assert_packet_checksums_valid(decrypt_pkt)
+                try:
+                    decrypt_pkt = vpp_tun_sa.decrypt(recv_pkt[IP])
+                    if not decrypt_pkt.haslayer(IP):
+                        decrypt_pkt = IP(decrypt_pkt[Raw].load)
+                    self.assert_equal(decrypt_pkt.src, self.pg1.remote_ip4)
+                    self.assert_equal(decrypt_pkt.dst, p.remote_tun_if_host)
+                    self.assert_packet_checksums_valid(decrypt_pkt)
+                except:
+                    self.logger.debug(ppp("Unexpected packet:", recv_pkt))
+                    try:
+                        self.logger.debug(
+                            ppp("Decrypted packet:", decrypt_pkt))
+                    except:
+                        pass
+                    raise
         finally:
             self.logger.info(self.vapi.ppcli("show error"))
             self.logger.info(self.vapi.ppcli("show ipsec"))
 
-    def test_tun_burst(self):
+    def test_tun_burst44(self):
         """ ipsec 4o4 tunnel burst test """
+        self.test_tun_basic44(count=257)
+
+
+class IpsecTun6Tests(object):
+    def test_tun_basic66(self, count=1):
+        """ ipsec 6o6 tunnel basic test """
         try:
-            self.test_tun_basic(count=257)
+            p = self.params[socket.AF_INET6]
+            vpp_tun_sa, scapy_tun_sa = self.configure_sa_tun(p)
+            send_pkts = self.gen_encrypt_pkts6(scapy_tun_sa, self.tun_if,
+                                               src=p.remote_tun_if_host,
+                                               dst=self.pg1.remote_ip6,
+                                               count=count)
+            recv_pkts = self.send_and_expect(self.tun_if, send_pkts, self.pg1)
+            for recv_pkt in recv_pkts:
+                self.assert_equal(recv_pkt[IPv6].src, p.remote_tun_if_host)
+                self.assert_equal(recv_pkt[IPv6].dst, self.pg1.remote_ip6)
+                self.assert_packet_checksums_valid(recv_pkt)
+            send_pkts = self.gen_pkts6(self.pg1, src=self.pg1.remote_ip6,
+                                       dst=p.remote_tun_if_host,
+                                       count=count)
+            recv_pkts = self.send_and_expect(self.pg1, send_pkts, self.tun_if)
+            for recv_pkt in recv_pkts:
+                try:
+                    decrypt_pkt = vpp_tun_sa.decrypt(recv_pkt[IPv6])
+                    if not decrypt_pkt.haslayer(IPv6):
+                        decrypt_pkt = IPv6(decrypt_pkt[Raw].load)
+                    self.assert_equal(decrypt_pkt.src, self.pg1.remote_ip6)
+                    self.assert_equal(decrypt_pkt.dst, p.remote_tun_if_host)
+                    self.assert_packet_checksums_valid(decrypt_pkt)
+                except:
+                    self.logger.debug(ppp("Unexpected packet:", recv_pkt))
+                    try:
+                        self.logger.debug(
+                            ppp("Decrypted packet:", decrypt_pkt))
+                    except:
+                        pass
+                    raise
         finally:
             self.logger.info(self.vapi.ppcli("show error"))
             self.logger.info(self.vapi.ppcli("show ipsec"))
 
+    def test_tun_burst66(self):
+        """ ipsec 6o6 tunnel burst test """
+        self.test_tun_basic66(count=257)
+
+
+class IpsecTunTests(IpsecTun4Tests, IpsecTun6Tests):
+    pass
+
 
 if __name__ == '__main__':
     unittest.main(testRunner=VppTestRunner)
index 729f871..59f6864 100644 (file)
@@ -37,8 +37,6 @@ class TemplateIpsecAh(TemplateIpsec):
      ---   decrypt   ---   plain   ---
     |pg0| ------->  |VPP| ------> |pg1|
      ---             ---           ---
-
-    Note : IPv6 is not covered
     """
 
     encryption_type = AH
@@ -49,100 +47,130 @@ class TemplateIpsecAh(TemplateIpsec):
         cls.tun_if = cls.pg0
         cls.tra_if = cls.pg2
         cls.logger.info(cls.vapi.ppcli("show int addr"))
-        cls.config_ah_tra()
+        cls.vapi.ipsec_spd_add_del(cls.tun_spd_id)
+        cls.vapi.ipsec_interface_add_del_spd(cls.tun_spd_id,
+                                             cls.tun_if.sw_if_index)
+        cls.vapi.ipsec_spd_add_del(cls.tra_spd_id)
+        cls.vapi.ipsec_interface_add_del_spd(cls.tra_spd_id,
+                                             cls.tra_if.sw_if_index)
+        for _, p in cls.params.items():
+            cls.config_ah_tra(p)
         cls.logger.info(cls.vapi.ppcli("show ipsec"))
-        cls.config_ah_tun()
+        for _, p in cls.params.items():
+            cls.config_ah_tun(p)
         cls.logger.info(cls.vapi.ppcli("show ipsec"))
-        src4 = socket.inet_pton(socket.AF_INET, cls.remote_tun_if_host)
-        cls.vapi.ip_add_del_route(src4, 32, cls.tun_if.remote_ip4n)
+        for _, p in cls.params.items():
+            src = socket.inet_pton(p.addr_type, p.remote_tun_if_host)
+            cls.vapi.ip_add_del_route(src, p.addr_len,
+                                      cls.tun_if.remote_addr_n[p.addr_type],
+                                      is_ipv6=p.is_ipv6)
 
     @classmethod
-    def config_ah_tun(cls):
-        cls.vapi.ipsec_sad_add_del_entry(cls.scapy_tun_sa_id,
-                                         cls.scapy_tun_spi,
-                                         cls.auth_algo_vpp_id, cls.auth_key,
-                                         cls.crypt_algo_vpp_id,
-                                         cls.crypt_key, cls.vpp_ah_protocol,
-                                         cls.tun_if.local_ip4n,
-                                         cls.tun_if.remote_ip4n)
-        cls.vapi.ipsec_sad_add_del_entry(cls.vpp_tun_sa_id,
-                                         cls.vpp_tun_spi,
-                                         cls.auth_algo_vpp_id, cls.auth_key,
-                                         cls.crypt_algo_vpp_id,
-                                         cls.crypt_key, cls.vpp_ah_protocol,
-                                         cls.tun_if.remote_ip4n,
-                                         cls.tun_if.local_ip4n)
-        cls.vapi.ipsec_spd_add_del(cls.tun_spd_id)
-        cls.vapi.ipsec_interface_add_del_spd(cls.tun_spd_id,
-                                             cls.tun_if.sw_if_index)
-        l_startaddr = r_startaddr = socket.inet_pton(socket.AF_INET, "0.0.0.0")
-        l_stopaddr = r_stopaddr = socket.inet_pton(socket.AF_INET,
-                                                   "255.255.255.255")
-        cls.vapi.ipsec_spd_add_del_entry(cls.tun_spd_id, cls.vpp_tun_sa_id,
+    def config_ah_tun(cls, params):
+        addr_type = params.addr_type
+        is_ipv6 = params.is_ipv6
+        scapy_tun_sa_id = params.scapy_tun_sa_id
+        scapy_tun_spi = params.scapy_tun_spi
+        vpp_tun_sa_id = params.vpp_tun_sa_id
+        vpp_tun_spi = params.vpp_tun_spi
+        auth_algo_vpp_id = params.auth_algo_vpp_id
+        auth_key = params.auth_key
+        crypt_algo_vpp_id = params.crypt_algo_vpp_id
+        crypt_key = params.crypt_key
+        remote_tun_if_host = params.remote_tun_if_host
+        addr_any = params.addr_any
+        addr_bcast = params.addr_bcast
+        cls.vapi.ipsec_sad_add_del_entry(scapy_tun_sa_id, scapy_tun_spi,
+                                         auth_algo_vpp_id, auth_key,
+                                         crypt_algo_vpp_id, crypt_key,
+                                         cls.vpp_ah_protocol,
+                                         cls.tun_if.local_addr_n[addr_type],
+                                         cls.tun_if.remote_addr_n[addr_type],
+                                         is_tunnel=1, is_tunnel_ipv6=is_ipv6)
+        cls.vapi.ipsec_sad_add_del_entry(vpp_tun_sa_id, vpp_tun_spi,
+                                         auth_algo_vpp_id, auth_key,
+                                         crypt_algo_vpp_id, crypt_key,
+                                         cls.vpp_ah_protocol,
+                                         cls.tun_if.remote_addr_n[addr_type],
+                                         cls.tun_if.local_addr_n[addr_type],
+                                         is_tunnel=1, is_tunnel_ipv6=is_ipv6)
+        l_startaddr = r_startaddr = socket.inet_pton(addr_type, addr_any)
+        l_stopaddr = r_stopaddr = socket.inet_pton(addr_type, addr_bcast)
+        cls.vapi.ipsec_spd_add_del_entry(cls.tun_spd_id, vpp_tun_sa_id,
                                          l_startaddr, l_stopaddr, r_startaddr,
-                                         r_stopaddr,
+                                         r_stopaddr, is_ipv6=is_ipv6,
                                          protocol=socket.IPPROTO_AH)
-        cls.vapi.ipsec_spd_add_del_entry(cls.tun_spd_id, cls.vpp_tun_sa_id,
+        cls.vapi.ipsec_spd_add_del_entry(cls.tun_spd_id, vpp_tun_sa_id,
                                          l_startaddr, l_stopaddr, r_startaddr,
                                          r_stopaddr, is_outbound=0,
+                                         is_ipv6=is_ipv6,
                                          protocol=socket.IPPROTO_AH)
-        l_startaddr = l_stopaddr = socket.inet_pton(socket.AF_INET,
-                                                    cls.remote_tun_if_host)
-        r_startaddr = r_stopaddr = cls.pg1.remote_ip4n
-        cls.vapi.ipsec_spd_add_del_entry(cls.tun_spd_id, cls.vpp_tun_sa_id,
+        l_startaddr = l_stopaddr = socket.inet_pton(addr_type,
+                                                    remote_tun_if_host)
+        r_startaddr = r_stopaddr = cls.pg1.remote_addr_n[addr_type]
+        cls.vapi.ipsec_spd_add_del_entry(cls.tun_spd_id, vpp_tun_sa_id,
                                          l_startaddr, l_stopaddr, r_startaddr,
                                          r_stopaddr, priority=10, policy=3,
-                                         is_outbound=0)
-        cls.vapi.ipsec_spd_add_del_entry(cls.tun_spd_id, cls.scapy_tun_sa_id,
+                                         is_outbound=0, is_ipv6=is_ipv6)
+        cls.vapi.ipsec_spd_add_del_entry(cls.tun_spd_id, scapy_tun_sa_id,
                                          r_startaddr, r_stopaddr, l_startaddr,
-                                         l_stopaddr, priority=10, policy=3)
-        r_startaddr = r_stopaddr = cls.pg0.local_ip4n
-        cls.vapi.ipsec_spd_add_del_entry(cls.tun_spd_id, cls.vpp_tun_sa_id,
+                                         l_stopaddr, priority=10, policy=3,
+                                         is_ipv6=is_ipv6)
+        r_startaddr = r_stopaddr = cls.pg0.local_addr_n[addr_type]
+        cls.vapi.ipsec_spd_add_del_entry(cls.tun_spd_id, vpp_tun_sa_id,
                                          l_startaddr, l_stopaddr, r_startaddr,
                                          r_stopaddr, priority=20, policy=3,
-                                         is_outbound=0)
-        cls.vapi.ipsec_spd_add_del_entry(cls.tun_spd_id, cls.scapy_tun_sa_id,
+                                         is_outbound=0, is_ipv6=is_ipv6)
+        cls.vapi.ipsec_spd_add_del_entry(cls.tun_spd_id, scapy_tun_sa_id,
                                          r_startaddr, r_stopaddr, l_startaddr,
-                                         l_stopaddr, priority=20, policy=3)
+                                         l_stopaddr, priority=20, policy=3,
+                                         is_ipv6=is_ipv6)
 
     @classmethod
-    def config_ah_tra(cls):
-        cls.vapi.ipsec_sad_add_del_entry(cls.scapy_tra_sa_id,
-                                         cls.scapy_tra_spi,
-                                         cls.auth_algo_vpp_id, cls.auth_key,
-                                         cls.crypt_algo_vpp_id,
-                                         cls.crypt_key, cls.vpp_ah_protocol,
-                                         is_tunnel=0)
-        cls.vapi.ipsec_sad_add_del_entry(cls.vpp_tra_sa_id,
-                                         cls.vpp_tra_spi,
-                                         cls.auth_algo_vpp_id, cls.auth_key,
-                                         cls.crypt_algo_vpp_id,
-                                         cls.crypt_key, cls.vpp_ah_protocol,
-                                         is_tunnel=0)
-        cls.vapi.ipsec_spd_add_del(cls.tra_spd_id)
-        cls.vapi.ipsec_interface_add_del_spd(cls.tra_spd_id,
-                                             cls.tra_if.sw_if_index)
-        l_startaddr = r_startaddr = socket.inet_pton(socket.AF_INET, "0.0.0.0")
-        l_stopaddr = r_stopaddr = socket.inet_pton(socket.AF_INET,
-                                                   "255.255.255.255")
-        cls.vapi.ipsec_spd_add_del_entry(cls.tra_spd_id, cls.vpp_tra_sa_id,
+    def config_ah_tra(cls, params):
+        addr_type = params.addr_type
+        is_ipv6 = params.is_ipv6
+        scapy_tra_sa_id = params.scapy_tra_sa_id
+        scapy_tra_spi = params.scapy_tra_spi
+        vpp_tra_sa_id = params.vpp_tra_sa_id
+        vpp_tra_spi = params.vpp_tra_spi
+        auth_algo_vpp_id = params.auth_algo_vpp_id
+        auth_key = params.auth_key
+        crypt_algo_vpp_id = params.crypt_algo_vpp_id
+        crypt_key = params.crypt_key
+        addr_any = params.addr_any
+        addr_bcast = params.addr_bcast
+        cls.vapi.ipsec_sad_add_del_entry(scapy_tra_sa_id, scapy_tra_spi,
+                                         auth_algo_vpp_id, auth_key,
+                                         crypt_algo_vpp_id, crypt_key,
+                                         cls.vpp_ah_protocol, is_tunnel=0,
+                                         is_tunnel_ipv6=0)
+        cls.vapi.ipsec_sad_add_del_entry(vpp_tra_sa_id, vpp_tra_spi,
+                                         auth_algo_vpp_id, auth_key,
+                                         crypt_algo_vpp_id, crypt_key,
+                                         cls.vpp_ah_protocol, is_tunnel=0,
+                                         is_tunnel_ipv6=0)
+        l_startaddr = r_startaddr = socket.inet_pton(addr_type, addr_any)
+        l_stopaddr = r_stopaddr = socket.inet_pton(addr_type, addr_bcast)
+        cls.vapi.ipsec_spd_add_del_entry(cls.tra_spd_id, vpp_tra_sa_id,
                                          l_startaddr, l_stopaddr, r_startaddr,
-                                         r_stopaddr,
+                                         r_stopaddr, is_ipv6=is_ipv6,
                                          protocol=socket.IPPROTO_AH)
-        cls.vapi.ipsec_spd_add_del_entry(cls.tra_spd_id, cls.scapy_tra_sa_id,
+        cls.vapi.ipsec_spd_add_del_entry(cls.tra_spd_id, scapy_tra_sa_id,
                                          l_startaddr, l_stopaddr, r_startaddr,
                                          r_stopaddr, is_outbound=0,
+                                         is_ipv6=is_ipv6,
                                          protocol=socket.IPPROTO_AH)
-        l_startaddr = l_stopaddr = cls.tra_if.local_ip4n
-        r_startaddr = r_stopaddr = cls.tra_if.remote_ip4n
-        cls.vapi.ipsec_spd_add_del_entry(cls.tra_spd_id, cls.vpp_tra_sa_id,
+        l_startaddr = l_stopaddr = cls.tra_if.local_addr_n[addr_type]
+        r_startaddr = r_stopaddr = cls.tra_if.remote_addr_n[addr_type]
+        cls.vapi.ipsec_spd_add_del_entry(cls.tra_spd_id, vpp_tra_sa_id,
                                          l_startaddr, l_stopaddr, r_startaddr,
                                          r_stopaddr, priority=10, policy=3,
-                                         is_outbound=0)
-        cls.vapi.ipsec_spd_add_del_entry(cls.tra_spd_id, cls.scapy_tra_sa_id,
+                                         is_outbound=0, is_ipv6=is_ipv6)
+        cls.vapi.ipsec_spd_add_del_entry(cls.tra_spd_id, scapy_tra_sa_id,
                                          l_startaddr, l_stopaddr, r_startaddr,
                                          r_stopaddr, priority=10,
-                                         policy=3)
+                                         policy=3, is_ipv6=is_ipv6)
 
     def tearDown(self):
         super(TemplateIpsecAh, self).tearDown()
index 58d159a..23cf660 100644 (file)
@@ -36,8 +36,6 @@ class TemplateIpsecEsp(TemplateIpsec):
      ---   decrypt   ---   plain   ---
     |pg0| ------->  |VPP| ------> |pg1|
      ---             ---           ---
-
-    Note : IPv6 is not covered
     """
 
     encryption_type = ESP
@@ -48,103 +46,130 @@ class TemplateIpsecEsp(TemplateIpsec):
         cls.tun_if = cls.pg0
         cls.tra_if = cls.pg2
         cls.logger.info(cls.vapi.ppcli("show int addr"))
-        cls.config_esp_tra()
-        cls.logger.info(cls.vapi.ppcli("show ipsec"))
-        cls.config_esp_tun()
+        cls.vapi.ipsec_spd_add_del(cls.tra_spd_id)
+        cls.vapi.ipsec_interface_add_del_spd(cls.tra_spd_id,
+                                             cls.tra_if.sw_if_index)
+        for _, p in cls.params.items():
+            cls.config_esp_tra(p)
         cls.logger.info(cls.vapi.ppcli("show ipsec"))
-        src4 = socket.inet_pton(socket.AF_INET, cls.remote_tun_if_host)
-        cls.vapi.ip_add_del_route(src4, 32, cls.tun_if.remote_ip4n)
-
-    @classmethod
-    def config_esp_tun(cls):
-        cls.vapi.ipsec_sad_add_del_entry(cls.scapy_tun_sa_id,
-                                         cls.scapy_tun_spi,
-                                         cls.auth_algo_vpp_id, cls.auth_key,
-                                         cls.crypt_algo_vpp_id,
-                                         cls.crypt_key, cls.vpp_esp_protocol,
-                                         cls.tun_if.local_ip4n,
-                                         cls.tun_if.remote_ip4n)
-        cls.vapi.ipsec_sad_add_del_entry(cls.vpp_tun_sa_id,
-                                         cls.vpp_tun_spi,
-                                         cls.auth_algo_vpp_id, cls.auth_key,
-                                         cls.crypt_algo_vpp_id,
-                                         cls.crypt_key, cls.vpp_esp_protocol,
-                                         cls.tun_if.remote_ip4n,
-                                         cls.tun_if.local_ip4n)
         cls.vapi.ipsec_spd_add_del(cls.tun_spd_id)
         cls.vapi.ipsec_interface_add_del_spd(cls.tun_spd_id,
                                              cls.tun_if.sw_if_index)
-        l_startaddr = r_startaddr = socket.inet_pton(socket.AF_INET,
-                                                     "0.0.0.0")
-        l_stopaddr = r_stopaddr = socket.inet_pton(socket.AF_INET,
-                                                   "255.255.255.255")
-        cls.vapi.ipsec_spd_add_del_entry(cls.tun_spd_id, cls.scapy_tun_sa_id,
+        for _, p in cls.params.items():
+            cls.config_esp_tun(p)
+        cls.logger.info(cls.vapi.ppcli("show ipsec"))
+        for _, p in cls.params.items():
+            src = socket.inet_pton(p.addr_type, p.remote_tun_if_host)
+            cls.vapi.ip_add_del_route(
+                src, p.addr_len, cls.tun_if.remote_addr_n[p.addr_type],
+                is_ipv6=p.is_ipv6)
+
+    @classmethod
+    def config_esp_tun(cls, params):
+        addr_type = params.addr_type
+        is_ipv6 = params.is_ipv6
+        scapy_tun_sa_id = params.scapy_tun_sa_id
+        scapy_tun_spi = params.scapy_tun_spi
+        vpp_tun_sa_id = params.vpp_tun_sa_id
+        vpp_tun_spi = params.vpp_tun_spi
+        auth_algo_vpp_id = params.auth_algo_vpp_id
+        auth_key = params.auth_key
+        crypt_algo_vpp_id = params.crypt_algo_vpp_id
+        crypt_key = params.crypt_key
+        remote_tun_if_host = params.remote_tun_if_host
+        addr_any = params.addr_any
+        addr_bcast = params.addr_bcast
+        cls.vapi.ipsec_sad_add_del_entry(scapy_tun_sa_id, scapy_tun_spi,
+                                         auth_algo_vpp_id, auth_key,
+                                         crypt_algo_vpp_id, crypt_key,
+                                         cls.vpp_esp_protocol,
+                                         cls.tun_if.local_addr_n[addr_type],
+                                         cls.tun_if.remote_addr_n[addr_type],
+                                         is_tunnel=1, is_tunnel_ipv6=is_ipv6)
+        cls.vapi.ipsec_sad_add_del_entry(vpp_tun_sa_id, vpp_tun_spi,
+                                         auth_algo_vpp_id, auth_key,
+                                         crypt_algo_vpp_id, crypt_key,
+                                         cls.vpp_esp_protocol,
+                                         cls.tun_if.remote_addr_n[addr_type],
+                                         cls.tun_if.local_addr_n[addr_type],
+                                         is_tunnel=1, is_tunnel_ipv6=is_ipv6)
+        l_startaddr = r_startaddr = socket.inet_pton(addr_type, addr_any)
+        l_stopaddr = r_stopaddr = socket.inet_pton(addr_type, addr_bcast)
+        cls.vapi.ipsec_spd_add_del_entry(cls.tun_spd_id, scapy_tun_sa_id,
                                          l_startaddr, l_stopaddr, r_startaddr,
-                                         r_stopaddr,
+                                         r_stopaddr, is_ipv6=is_ipv6,
                                          protocol=socket.IPPROTO_ESP)
-        cls.vapi.ipsec_spd_add_del_entry(cls.tun_spd_id, cls.scapy_tun_sa_id,
+        cls.vapi.ipsec_spd_add_del_entry(cls.tun_spd_id, scapy_tun_sa_id,
                                          l_startaddr, l_stopaddr, r_startaddr,
                                          r_stopaddr, is_outbound=0,
-                                         protocol=socket.IPPROTO_ESP)
-        l_startaddr = l_stopaddr = socket.inet_pton(socket.AF_INET,
-                                                    cls.remote_tun_if_host)
-        r_startaddr = r_stopaddr = cls.pg1.remote_ip4n
-        cls.vapi.ipsec_spd_add_del_entry(cls.tun_spd_id, cls.vpp_tun_sa_id,
+                                         protocol=socket.IPPROTO_ESP,
+                                         is_ipv6=is_ipv6)
+        l_startaddr = l_stopaddr = socket.inet_pton(addr_type,
+                                                    remote_tun_if_host)
+        r_startaddr = r_stopaddr = cls.pg1.remote_addr_n[addr_type]
+        cls.vapi.ipsec_spd_add_del_entry(cls.tun_spd_id, vpp_tun_sa_id,
                                          l_startaddr, l_stopaddr, r_startaddr,
                                          r_stopaddr, priority=10, policy=3,
-                                         is_outbound=0)
-        cls.vapi.ipsec_spd_add_del_entry(cls.tun_spd_id, cls.scapy_tun_sa_id,
+                                         is_ipv6=is_ipv6, is_outbound=0)
+        cls.vapi.ipsec_spd_add_del_entry(cls.tun_spd_id, scapy_tun_sa_id,
                                          r_startaddr, r_stopaddr, l_startaddr,
-                                         l_stopaddr, priority=10, policy=3)
-        l_startaddr = l_stopaddr = socket.inet_pton(socket.AF_INET,
-                                                    cls.remote_tun_if_host)
-        r_startaddr = r_stopaddr = cls.pg0.local_ip4n
-        cls.vapi.ipsec_spd_add_del_entry(cls.tun_spd_id, cls.vpp_tun_sa_id,
+                                         l_stopaddr, priority=10, policy=3,
+                                         is_ipv6=is_ipv6)
+        l_startaddr = l_stopaddr = socket.inet_pton(addr_type,
+                                                    remote_tun_if_host)
+        r_startaddr = r_stopaddr = cls.pg0.local_addr_n[addr_type]
+        cls.vapi.ipsec_spd_add_del_entry(cls.tun_spd_id, vpp_tun_sa_id,
                                          l_startaddr, l_stopaddr, r_startaddr,
                                          r_stopaddr, priority=20, policy=3,
-                                         is_outbound=0)
-        cls.vapi.ipsec_spd_add_del_entry(cls.tun_spd_id, cls.scapy_tun_sa_id,
+                                         is_outbound=0, is_ipv6=is_ipv6)
+        cls.vapi.ipsec_spd_add_del_entry(cls.tun_spd_id, scapy_tun_sa_id,
                                          r_startaddr, r_stopaddr, l_startaddr,
-                                         l_stopaddr, priority=20, policy=3)
+                                         l_stopaddr, priority=20, policy=3,
+                                         is_ipv6=is_ipv6)
 
     @classmethod
-    def config_esp_tra(cls):
-        cls.vapi.ipsec_sad_add_del_entry(cls.scapy_tra_sa_id,
-                                         cls.scapy_tra_spi,
-                                         cls.auth_algo_vpp_id, cls.auth_key,
-                                         cls.crypt_algo_vpp_id,
-                                         cls.crypt_key, cls.vpp_esp_protocol,
-                                         is_tunnel=0)
-        cls.vapi.ipsec_sad_add_del_entry(cls.vpp_tra_sa_id,
-                                         cls.vpp_tra_spi,
-                                         cls.auth_algo_vpp_id, cls.auth_key,
-                                         cls.crypt_algo_vpp_id,
-                                         cls.crypt_key, cls.vpp_esp_protocol,
-                                         is_tunnel=0)
-        cls.vapi.ipsec_spd_add_del(cls.tra_spd_id)
-        cls.vapi.ipsec_interface_add_del_spd(cls.tra_spd_id,
-                                             cls.tra_if.sw_if_index)
-        l_startaddr = r_startaddr = socket.inet_pton(socket.AF_INET,
-                                                     "0.0.0.0")
-        l_stopaddr = r_stopaddr = socket.inet_pton(socket.AF_INET,
-                                                   "255.255.255.255")
-        cls.vapi.ipsec_spd_add_del_entry(cls.tra_spd_id, cls.vpp_tra_sa_id,
+    def config_esp_tra(cls, params):
+        addr_type = params.addr_type
+        is_ipv6 = params.is_ipv6
+        scapy_tra_sa_id = params.scapy_tra_sa_id
+        scapy_tra_spi = params.scapy_tra_spi
+        vpp_tra_sa_id = params.vpp_tra_sa_id
+        vpp_tra_spi = params.vpp_tra_spi
+        auth_algo_vpp_id = params.auth_algo_vpp_id
+        auth_key = params.auth_key
+        crypt_algo_vpp_id = params.crypt_algo_vpp_id
+        crypt_key = params.crypt_key
+        addr_any = params.addr_any
+        addr_bcast = params.addr_bcast
+        cls.vapi.ipsec_sad_add_del_entry(scapy_tra_sa_id, scapy_tra_spi,
+                                         auth_algo_vpp_id, auth_key,
+                                         crypt_algo_vpp_id, crypt_key,
+                                         cls.vpp_esp_protocol, is_tunnel=0)
+        cls.vapi.ipsec_sad_add_del_entry(vpp_tra_sa_id, vpp_tra_spi,
+                                         auth_algo_vpp_id, auth_key,
+                                         crypt_algo_vpp_id, crypt_key,
+                                         cls.vpp_esp_protocol, is_tunnel=0)
+        l_startaddr = r_startaddr = socket.inet_pton(addr_type, addr_any)
+        l_stopaddr = r_stopaddr = socket.inet_pton(addr_type, addr_bcast)
+        cls.vapi.ipsec_spd_add_del_entry(cls.tra_spd_id, vpp_tra_sa_id,
                                          l_startaddr, l_stopaddr, r_startaddr,
-                                         r_stopaddr,
+                                         r_stopaddr, is_ipv6=is_ipv6,
                                          protocol=socket.IPPROTO_ESP)
-        cls.vapi.ipsec_spd_add_del_entry(cls.tra_spd_id, cls.vpp_tra_sa_id,
+        cls.vapi.ipsec_spd_add_del_entry(cls.tra_spd_id, vpp_tra_sa_id,
                                          l_startaddr, l_stopaddr, r_startaddr,
                                          r_stopaddr, is_outbound=0,
+                                         is_ipv6=is_ipv6,
                                          protocol=socket.IPPROTO_ESP)
-        l_startaddr = l_stopaddr = cls.tra_if.local_ip4n
-        r_startaddr = r_stopaddr = cls.tra_if.remote_ip4n
-        cls.vapi.ipsec_spd_add_del_entry(cls.tra_spd_id, cls.vpp_tra_sa_id,
+        l_startaddr = l_stopaddr = cls.tra_if.local_addr_n[addr_type]
+        r_startaddr = r_stopaddr = cls.tra_if.remote_addr_n[addr_type]
+        cls.vapi.ipsec_spd_add_del_entry(cls.tra_spd_id, vpp_tra_sa_id,
                                          l_startaddr, l_stopaddr, r_startaddr,
                                          r_stopaddr, priority=10, policy=3,
-                                         is_outbound=0)
-        cls.vapi.ipsec_spd_add_del_entry(cls.tra_spd_id, cls.scapy_tra_sa_id,
+                                         is_outbound=0, is_ipv6=is_ipv6)
+        cls.vapi.ipsec_spd_add_del_entry(cls.tra_spd_id, scapy_tra_sa_id,
                                          l_startaddr, l_stopaddr, r_startaddr,
-                                         r_stopaddr, priority=10, policy=3)
+                                         r_stopaddr, priority=10, policy=3,
+                                         is_ipv6=is_ipv6)
 
 
 class TestIpsecEsp1(TemplateIpsecEsp, IpsecTraTests, IpsecTunTests):
index 9e0b9ea..e9efa03 100644 (file)
@@ -35,10 +35,16 @@ class IPSecNATTestCase(TemplateIpsec):
     def setUpClass(cls):
         super(IPSecNATTestCase, cls).setUpClass()
         cls.tun_if = cls.pg0
-        cls.config_esp_tun()
+        cls.vapi.ipsec_spd_add_del(cls.tun_spd_id)
+        cls.vapi.ipsec_interface_add_del_spd(cls.tun_spd_id,
+                                             cls.tun_if.sw_if_index)
+        p = cls.ipv4_params
+        cls.config_esp_tun(p)
         cls.logger.info(cls.vapi.ppcli("show ipsec"))
-        client = socket.inet_pton(socket.AF_INET, cls.remote_tun_if_host)
-        cls.vapi.ip_add_del_route(client, 32, cls.tun_if.remote_ip4n)
+        src = socket.inet_pton(p.addr_type, p.remote_tun_if_host)
+        cls.vapi.ip_add_del_route(src, p.addr_len,
+                                  cls.tun_if.remote_addr_n[p.addr_type],
+                                  is_ipv6=p.is_ipv6)
 
     def create_stream_plain(self, src_mac, dst_mac, src_ip, dst_ip):
         return [
@@ -126,66 +132,71 @@ class IPSecNATTestCase(TemplateIpsec):
                 raise
 
     @classmethod
-    def config_esp_tun(cls):
-        cls.vapi.ipsec_sad_add_del_entry(cls.scapy_tun_sa_id,
-                                         cls.scapy_tun_spi,
-                                         cls.auth_algo_vpp_id, cls.auth_key,
-                                         cls.crypt_algo_vpp_id,
-                                         cls.crypt_key, cls.vpp_esp_protocol,
-                                         cls.pg1.remote_ip4n,
-                                         cls.tun_if.remote_ip4n,
+    def config_esp_tun(cls, params):
+        addr_type = params.addr_type
+        scapy_tun_sa_id = params.scapy_tun_sa_id
+        scapy_tun_spi = params.scapy_tun_spi
+        vpp_tun_sa_id = params.vpp_tun_sa_id
+        vpp_tun_spi = params.vpp_tun_spi
+        auth_algo_vpp_id = params.auth_algo_vpp_id
+        auth_key = params.auth_key
+        crypt_algo_vpp_id = params.crypt_algo_vpp_id
+        crypt_key = params.crypt_key
+        addr_any = params.addr_any
+        addr_bcast = params.addr_bcast
+        cls.vapi.ipsec_sad_add_del_entry(scapy_tun_sa_id, scapy_tun_spi,
+                                         auth_algo_vpp_id, auth_key,
+                                         crypt_algo_vpp_id, crypt_key,
+                                         cls.vpp_esp_protocol,
+                                         cls.pg1.remote_addr_n[addr_type],
+                                         cls.tun_if.remote_addr_n[addr_type],
                                          udp_encap=1)
-        cls.vapi.ipsec_sad_add_del_entry(cls.vpp_tun_sa_id,
-                                         cls.vpp_tun_spi,
-                                         cls.auth_algo_vpp_id, cls.auth_key,
-                                         cls.crypt_algo_vpp_id,
-                                         cls.crypt_key, cls.vpp_esp_protocol,
-                                         cls.tun_if.remote_ip4n,
-                                         cls.pg1.remote_ip4n,
+        cls.vapi.ipsec_sad_add_del_entry(vpp_tun_sa_id, vpp_tun_spi,
+                                         auth_algo_vpp_id, auth_key,
+                                         crypt_algo_vpp_id, crypt_key,
+                                         cls.vpp_esp_protocol,
+                                         cls.tun_if.remote_addr_n[addr_type],
+                                         cls.pg1.remote_addr_n[addr_type],
                                          udp_encap=1)
-        cls.vapi.ipsec_spd_add_del(cls.tun_spd_id)
-        cls.vapi.ipsec_interface_add_del_spd(cls.tun_spd_id,
-                                             cls.tun_if.sw_if_index)
-        l_startaddr = r_startaddr = socket.inet_pton(socket.AF_INET,
-                                                     "0.0.0.0")
-        l_stopaddr = r_stopaddr = socket.inet_pton(socket.AF_INET,
-                                                   "255.255.255.255")
-        cls.vapi.ipsec_spd_add_del_entry(cls.tun_spd_id, cls.scapy_tun_sa_id,
+        l_startaddr = r_startaddr = socket.inet_pton(addr_type, addr_any)
+        l_stopaddr = r_stopaddr = socket.inet_pton(addr_type, addr_bcast)
+        cls.vapi.ipsec_spd_add_del_entry(cls.tun_spd_id, scapy_tun_sa_id,
                                          l_startaddr, l_stopaddr, r_startaddr,
                                          r_stopaddr,
                                          protocol=socket.IPPROTO_ESP)
-        cls.vapi.ipsec_spd_add_del_entry(cls.tun_spd_id, cls.scapy_tun_sa_id,
+        cls.vapi.ipsec_spd_add_del_entry(cls.tun_spd_id, scapy_tun_sa_id,
                                          l_startaddr, l_stopaddr, r_startaddr,
                                          r_stopaddr, is_outbound=0,
                                          protocol=socket.IPPROTO_ESP)
-        cls.vapi.ipsec_spd_add_del_entry(cls.tun_spd_id, cls.scapy_tun_sa_id,
+        cls.vapi.ipsec_spd_add_del_entry(cls.tun_spd_id, scapy_tun_sa_id,
                                          l_startaddr, l_stopaddr, r_startaddr,
                                          r_stopaddr, remote_port_start=4500,
                                          remote_port_stop=4500,
                                          protocol=socket.IPPROTO_UDP)
-        cls.vapi.ipsec_spd_add_del_entry(cls.tun_spd_id, cls.scapy_tun_sa_id,
+        cls.vapi.ipsec_spd_add_del_entry(cls.tun_spd_id, scapy_tun_sa_id,
                                          l_startaddr, l_stopaddr, r_startaddr,
                                          r_stopaddr, remote_port_start=4500,
                                          remote_port_stop=4500,
                                          protocol=socket.IPPROTO_UDP,
                                          is_outbound=0)
-        l_startaddr = l_stopaddr = cls.tun_if.remote_ip4n
-        r_startaddr = r_stopaddr = cls.pg1.remote_ip4n
-        cls.vapi.ipsec_spd_add_del_entry(cls.tun_spd_id, cls.vpp_tun_sa_id,
+        l_startaddr = l_stopaddr = cls.tun_if.remote_addr_n[addr_type]
+        r_startaddr = r_stopaddr = cls.pg1.remote_addr_n[addr_type]
+        cls.vapi.ipsec_spd_add_del_entry(cls.tun_spd_id, vpp_tun_sa_id,
                                          l_startaddr, l_stopaddr, r_startaddr,
                                          r_stopaddr, priority=10, policy=3,
                                          is_outbound=0)
-        cls.vapi.ipsec_spd_add_del_entry(cls.tun_spd_id, cls.scapy_tun_sa_id,
+        cls.vapi.ipsec_spd_add_del_entry(cls.tun_spd_id, scapy_tun_sa_id,
                                          r_startaddr, r_stopaddr, l_startaddr,
                                          l_stopaddr, priority=10, policy=3)
 
     def test_ipsec_nat_tun(self):
         """ IPSec/NAT tunnel test case """
-        scapy_tun_sa = SecurityAssociation(ESP, spi=self.scapy_tun_spi,
-                                           crypt_algo=self.crypt_algo,
-                                           crypt_key=self.crypt_key,
-                                           auth_algo=self.auth_algo,
-                                           auth_key=self.auth_key,
+        p = self.ipv4_params
+        scapy_tun_sa = SecurityAssociation(ESP, spi=p.scapy_tun_spi,
+                                           crypt_algo=p.crypt_algo,
+                                           crypt_key=p.crypt_key,
+                                           auth_algo=p.auth_algo,
+                                           auth_key=p.auth_key,
                                            tunnel_header=IP(
                                                src=self.pg1.remote_ip4,
                                                dst=self.tun_if.remote_ip4),
@@ -203,11 +214,11 @@ class IPSecNATTestCase(TemplateIpsec):
         self.verify_capture_encrypted(capture, scapy_tun_sa)
 
         vpp_tun_sa = SecurityAssociation(ESP,
-                                         spi=self.vpp_tun_spi,
-                                         crypt_algo=self.crypt_algo,
-                                         crypt_key=self.crypt_key,
-                                         auth_algo=self.auth_algo,
-                                         auth_key=self.auth_key,
+                                         spi=p.vpp_tun_spi,
+                                         crypt_algo=p.crypt_algo,
+                                         crypt_key=p.crypt_key,
+                                         auth_algo=p.auth_algo,
+                                         auth_key=p.auth_key,
                                          tunnel_header=IP(
                                              src=self.tun_if.remote_ip4,
                                              dst=self.pg1.remote_ip4),
index c260f03..292458d 100644 (file)
@@ -2,7 +2,7 @@ import unittest
 import socket
 from scapy.layers.ipsec import ESP
 from framework import VppTestRunner
-from template_ipsec import TemplateIpsec, IpsecTunTests, IpsecTcpTests
+from template_ipsec import TemplateIpsec, IpsecTun4Tests, IpsecTcpTests
 from vpp_ipsec_tun_interface import VppIpsecTunInterface
 
 
@@ -17,20 +17,17 @@ class TemplateIpsecTunIfEsp(TemplateIpsec):
         cls.tun_if = cls.pg0
 
     def setUp(self):
-        self.ipsec_tun_if = VppIpsecTunInterface(self, self.pg0,
-                                                 self.vpp_tun_spi,
-                                                 self.scapy_tun_spi,
-                                                 self.crypt_algo_vpp_id,
-                                                 self.crypt_key,
-                                                 self.crypt_key,
-                                                 self.auth_algo_vpp_id,
-                                                 self.auth_key,
-                                                 self.auth_key)
-        self.ipsec_tun_if.add_vpp_config()
-        self.ipsec_tun_if.admin_up()
-        self.ipsec_tun_if.config_ip4()
-        src4 = socket.inet_pton(socket.AF_INET, self.remote_tun_if_host)
-        self.vapi.ip_add_del_route(src4, 32, self.ipsec_tun_if.remote_ip4n)
+        p = self.ipv4_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)
+        tun_if.add_vpp_config()
+        tun_if.admin_up()
+        tun_if.config_ip4()
+        src4 = socket.inet_pton(socket.AF_INET, p.remote_tun_if_host)
+        self.vapi.ip_add_del_route(src4, 32, tun_if.remote_ip4n)
 
     def tearDown(self):
         if not self.vpp_dead:
@@ -38,7 +35,7 @@ class TemplateIpsecTunIfEsp(TemplateIpsec):
         super(TemplateIpsecTunIfEsp, self).tearDown()
 
 
-class TestIpsecTunIfEsp1(TemplateIpsecTunIfEsp, IpsecTunTests):
+class TestIpsecTunIfEsp1(TemplateIpsecTunIfEsp, IpsecTun4Tests):
     """ Ipsec ESP - TUN tests """
     pass
 
index 65e25f7..d8ecf27 100644 (file)
@@ -11,6 +11,7 @@ from scapy.packet import Raw
 from scapy.layers.inet import IP
 from scapy.layers.inet6 import IPv6, IPv6ExtHdrFragment, IPv6ExtHdrRouting,\
     IPv6ExtHdrHopByHop
+from scapy.utils import hexdump
 from socket import AF_INET6
 
 
@@ -20,6 +21,8 @@ def ppp(headline, packet):
     old_stdout = sys.stdout
     sys.stdout = o
     print(headline)
+    hexdump(packet)
+    print("")
     packet.show()
     sys.stdout = old_stdout
     return o.getvalue()
index 1db34ba..65f3c44 100644 (file)
@@ -23,6 +23,22 @@ class VppInterface(object):
         """MAC-address of the VPP interface."""
         return self._local_mac
 
+    @property
+    def local_addr(self):
+        return self._local_addr
+
+    @property
+    def remote_addr(self):
+        return self._remote_addr
+
+    @property
+    def local_addr_n(self):
+        return self._local_addr_n
+
+    @property
+    def remote_addr_n(self):
+        return self._remote_addr_n
+
     @property
     def local_ip4(self):
         """Local IPv4 address on VPP interface (string)."""
@@ -65,7 +81,7 @@ class VppInterface(object):
 
     @property
     def local_ip6_ll(self):
-        """Local IPv6 linnk-local address on VPP interface (string)."""
+        """Local IPv6 link-local address on VPP interface (string)."""
         return self._local_ip6_ll
 
     @property
@@ -200,6 +216,15 @@ class VppInterface(object):
         self.has_ip6_config = False
         self.ip6_table_id = 0
 
+        self._local_addr = {socket.AF_INET: self.local_ip4,
+                            socket.AF_INET6: self.local_ip6}
+        self._local_addr_n = {socket.AF_INET: self.local_ip4n,
+                              socket.AF_INET6: self.local_ip6n}
+        self._remote_addr = {socket.AF_INET: self.remote_ip4,
+                             socket.AF_INET6: self.remote_ip6}
+        self._remote_addr_n = {socket.AF_INET: self.remote_ip4n,
+                               socket.AF_INET6: self.remote_ip6n}
+
         r = self.test.vapi.sw_interface_dump()
         for intf in r:
             if intf.sw_if_index == self.sw_if_index:
index a51dea4..57592e8 100644 (file)
@@ -71,7 +71,7 @@ class VppPapiProvider(object):
 
     _zero, _negative = range(2)
 
-    def __init__(self, name, shm_prefix, test_class):
+    def __init__(self, name, shm_prefix, test_class, read_timeout):
         self.hook = Hook("vpp-papi-provider")
         self.name = name
         self.shm_prefix = shm_prefix
@@ -85,7 +85,8 @@ class VppPapiProvider(object):
             for filename in fnmatch.filter(filenames, '*.api.json'):
                 jsonfiles.append(os.path.join(root, filename))
 
-        self.vpp = VPP(jsonfiles, logger=test_class.logger, read_timeout=5)
+        self.vpp = VPP(jsonfiles, logger=test_class.logger,
+                       read_timeout=read_timeout)
         self._events = deque()
 
     def __enter__(self):
@@ -3312,6 +3313,7 @@ class VppPapiProvider(object):
                                 tunnel_src_address='',
                                 tunnel_dst_address='',
                                 is_tunnel=1,
+                                is_tunnel_ipv6=0,
                                 is_add=1,
                                 udp_encap=0):
         """ IPSEC SA add/del
@@ -3345,6 +3347,7 @@ class VppPapiProvider(object):
              'crypto_key': crypto_key,
              'is_add': is_add,
              'is_tunnel': is_tunnel,
+             'is_tunnel_ipv6': is_tunnel_ipv6,
              'udp_encap': udp_encap})
 
     def ipsec_spd_add_del_entry(self,
@@ -3363,6 +3366,7 @@ class VppPapiProvider(object):
                                 priority=100,
                                 is_outbound=1,
                                 is_add=1,
+                                is_ipv6=0,
                                 is_ip_any=0):
         """ IPSEC policy SPD add/del   -
                     Wrapper to configure ipsec SPD policy entries in VPP
@@ -3401,6 +3405,7 @@ class VppPapiProvider(object):
              'policy': policy,
              'priority': priority,
              'is_outbound': is_outbound,
+             'is_ipv6': is_ipv6,
              'is_ip_any': is_ip_any})
 
     def ipsec_tunnel_if_add_del(self, local_ip, remote_ip, local_spi,