ipsec: ipsec-tun protect
[vpp.git] / src / vnet / ipsec / esp_encrypt.c
index 3aafaff..cf48548 100644 (file)
@@ -257,7 +257,7 @@ esp_encrypt_inline (vlib_main_t * vm, vlib_node_runtime_t * node,
 
   while (n_left > 0)
     {
-      u32 sa_index0 = vnet_buffer (b[0])->ipsec.sad_index;
+      u32 sa_index0;
       dpo_id_t *dpo;
       esp_header_t *esp;
       u8 *payload, *next_hdr_ptr;
@@ -288,12 +288,15 @@ esp_encrypt_inline (vlib_main_t * vm, vlib_node_runtime_t * node,
 
       if (sa_index0 != current_sa_index)
        {
+         if (current_sa_packets)
+           vlib_increment_combined_counter (&ipsec_sa_counters, thread_index,
+                                            current_sa_index,
+                                            current_sa_packets,
+                                            current_sa_bytes);
+         current_sa_packets = current_sa_bytes = 0;
+
          sa0 = pool_elt_at_index (im->sad, sa_index0);
          current_sa_index = sa_index0;
-         vlib_increment_combined_counter (&ipsec_sa_counters, thread_index,
-                                          sa_index0, current_sa_packets,
-                                          current_sa_bytes);
-         current_sa_packets = current_sa_bytes = 0;
          spi = clib_net_to_host_u32 (sa0->spi);
          block_sz = sa0->crypto_block_size;
          icv_sz = sa0->integ_icv_size;
@@ -364,7 +367,7 @@ esp_encrypt_inline (vlib_main_t * vm, vlib_node_runtime_t * node,
              esp_update_ip4_hdr (ip4, len, /* is_transport */ 0, 0);
            }
 
-         dpo = sa0->dpo + IPSEC_PROTOCOL_ESP;
+         dpo = &sa0->dpo;
          if (!is_tun)
            {
              next[0] = dpo->dpoi_next_node;
@@ -405,12 +408,18 @@ esp_encrypt_inline (vlib_main_t * vm, vlib_node_runtime_t * node,
          ip_hdr = payload - hdr_len;
 
          /* L2 header */
-         l2_len = vnet_buffer (b[0])->ip.save_rewrite_length;
-         hdr_len += l2_len;
-         l2_hdr = payload - hdr_len;
+         if (!is_tun)
+           {
+             l2_len = vnet_buffer (b[0])->ip.save_rewrite_length;
+             hdr_len += l2_len;
+             l2_hdr = payload - hdr_len;
+
+             /* copy l2 and ip header */
+             clib_memcpy_le32 (l2_hdr, old_ip_hdr - l2_len, l2_len);
+           }
+         else
+           l2_len = 0;
 
-         /* copy l2 and ip header */
-         clib_memcpy_le32 (l2_hdr, old_ip_hdr - l2_len, l2_len);
          clib_memcpy_le64 (ip_hdr, old_ip_hdr, ip_len);
 
          if (is_ip6)
@@ -437,7 +446,8 @@ esp_encrypt_inline (vlib_main_t * vm, vlib_node_runtime_t * node,
                esp_update_ip4_hdr (ip4, len, /* is_transport */ 1, 0);
            }
 
-         next[0] = ESP_ENCRYPT_NEXT_INTERFACE_OUTPUT;
+         if (!is_tun)
+           next[0] = ESP_ENCRYPT_NEXT_INTERFACE_OUTPUT;
        }
 
       esp->spi = spi;
@@ -615,6 +625,13 @@ VNET_FEATURE_INIT (esp4_encrypt_tun_feat_node, static) =
   .node_name = "esp4-encrypt-tun",
   .runs_before = VNET_FEATURES ("adj-midchain-tx"),
 };
+
+VNET_FEATURE_INIT (esp4_ethernet_encrypt_tun_feat_node, static) =
+{
+  .arc_name = "ethernet-output",
+  .node_name = "esp4-encrypt-tun",
+  .runs_before = VNET_FEATURES ("adj-midchain-tx", "adj-midchain-tx-no-count"),
+};
 /* *INDENT-ON* */
 
 VLIB_NODE_FN (esp6_encrypt_tun_node) (vlib_main_t * vm,