ipsec: USE_EXTENDED_SEQ_NUM -> USE_ESN
[vpp.git] / src / vnet / ipsec / esp_encrypt.c
index c792a14..fc1fe39 100644 (file)
@@ -220,7 +220,7 @@ esp_process_ops (vlib_main_t * vm, vlib_node_runtime_t * node,
 
 always_inline uword
 esp_encrypt_inline (vlib_main_t * vm, vlib_node_runtime_t * node,
-                   vlib_frame_t * frame, int is_ip6)
+                   vlib_frame_t * frame, int is_ip6, int is_tun)
 {
   ipsec_main_t *im = &ipsec_main;
   ipsec_per_thread_data_t *ptd = vec_elt_at_index (im->ptd, vm->thread_index);
@@ -258,7 +258,19 @@ esp_encrypt_inline (vlib_main_t * vm, vlib_node_runtime_t * node,
          CLIB_PREFETCH (p, CLIB_CACHE_LINE_BYTES, LOAD);
        }
 
-      if (vnet_buffer (b[0])->ipsec.sad_index != current_sa_index)
+      if (is_tun)
+       {
+         /* we are on a ipsec tunnel's feature arc */
+         u32 next0;
+         sa_index0 = *(u32 *) vnet_feature_next_with_data (&next0, b[0],
+                                                           sizeof
+                                                           (sa_index0));
+         next[0] = next0;
+       }
+      else
+       sa_index0 = vnet_buffer (b[0])->ipsec.sad_index;
+
+      if (sa_index0 != current_sa_index)
        {
          sa0 = pool_elt_at_index (im->sad, sa_index0);
          current_sa_index = sa_index0;
@@ -289,7 +301,7 @@ esp_encrypt_inline (vlib_main_t * vm, vlib_node_runtime_t * node,
       /* space for IV */
       hdr_len = iv_sz;
 
-      if (sa0->is_tunnel)
+      if (ipsec_sa_is_set_IS_TUNNEL (sa0))
        {
          payload = vlib_buffer_get_current (b[0]);
          next_hdr_ptr = esp_add_footer_and_icv (b[0], block_sz, icv_sz);
@@ -303,7 +315,7 @@ esp_encrypt_inline (vlib_main_t * vm, vlib_node_runtime_t * node,
          esp = (esp_header_t *) (payload - hdr_len);
 
          /* optional UDP header */
-         if (sa0->udp_encap)
+         if (ipsec_sa_is_set_UDP_ENCAP (sa0))
            {
              hdr_len += sizeof (udp_header_t);
              esp_fill_udp_hdr (sa0, (udp_header_t *) (payload - hdr_len),
@@ -311,14 +323,15 @@ esp_encrypt_inline (vlib_main_t * vm, vlib_node_runtime_t * node,
            }
 
          /* IP header */
-         if (sa0->is_tunnel_ip6)
+         if (ipsec_sa_is_set_IS_TUNNEL_V6 (sa0))
            {
              ip6_header_t *ip6;
              u16 len = sizeof (ip6_header_t);
              hdr_len += len;
              ip6 = (ip6_header_t *) (payload - hdr_len);
              clib_memcpy_fast (ip6, &sa0->ip6_hdr, len);
-             *next_hdr_ptr = IP_PROTOCOL_IPV6;
+             *next_hdr_ptr = (is_ip6 ?
+                              IP_PROTOCOL_IPV6 : IP_PROTOCOL_IP_IN_IP);
              len = payload_len + hdr_len - len;
              ip6->payload_length = clib_net_to_host_u16 (len);
            }
@@ -329,14 +342,18 @@ esp_encrypt_inline (vlib_main_t * vm, vlib_node_runtime_t * node,
              hdr_len += len;
              ip4 = (ip4_header_t *) (payload - hdr_len);
              clib_memcpy_fast (ip4, &sa0->ip4_hdr, len);
-             *next_hdr_ptr = IP_PROTOCOL_IP_IN_IP;
+             *next_hdr_ptr = (is_ip6 ?
+                              IP_PROTOCOL_IPV6 : IP_PROTOCOL_IP_IN_IP);
              len = payload_len + hdr_len;
              esp_update_ip4_hdr (ip4, len, /* is_transport */ 0, 0);
            }
 
          dpo = sa0->dpo + IPSEC_PROTOCOL_ESP;
-         next[0] = dpo->dpoi_next_node;
-         vnet_buffer (b[0])->ip.adj_index[VLIB_TX] = dpo->dpoi_index;
+         if (!is_tun)
+           {
+             next[0] = dpo->dpoi_next_node;
+             vnet_buffer (b[0])->ip.adj_index[VLIB_TX] = dpo->dpoi_index;
+           }
        }
       else                     /* transport mode */
        {
@@ -361,7 +378,7 @@ esp_encrypt_inline (vlib_main_t * vm, vlib_node_runtime_t * node,
          esp = (esp_header_t *) (payload - hdr_len);
 
          /* optional UDP header */
-         if (sa0->udp_encap)
+         if (ipsec_sa_is_set_UDP_ENCAP (sa0))
            {
              hdr_len += sizeof (udp_header_t);
              udp = (udp_header_t *) (payload - hdr_len);
@@ -434,7 +451,7 @@ esp_encrypt_inline (vlib_main_t * vm, vlib_node_runtime_t * node,
          op->len = payload_len - icv_sz + iv_sz + sizeof (esp_header_t);
          op->flags = 0;
          op->user_data = b - bufs;
-         if (sa0->use_esn)
+         if (ipsec_sa_is_set_USE_ESN (sa0))
            {
              u32 seq_hi = clib_net_to_host_u32 (sa0->seq_hi);
              clib_memcpy_fast (op->dst, &seq_hi, sizeof (seq_hi));
@@ -455,7 +472,7 @@ esp_encrypt_inline (vlib_main_t * vm, vlib_node_runtime_t * node,
          tr->sa_index = sa_index0;
          tr->spi = sa0->spi;
          tr->seq = sa0->seq - 1;
-         tr->udp_encap = sa0->udp_encap;
+         tr->udp_encap = ipsec_sa_is_set_UDP_ENCAP (sa0);
          tr->crypto_alg = sa0->crypto_alg;
          tr->integ_alg = sa0->integ_alg;
        }
@@ -483,7 +500,7 @@ VLIB_NODE_FN (esp4_encrypt_node) (vlib_main_t * vm,
                                  vlib_node_runtime_t * node,
                                  vlib_frame_t * from_frame)
 {
-  return esp_encrypt_inline (vm, node, from_frame, 0 /* is_ip6 */ );
+  return esp_encrypt_inline (vm, node, from_frame, 0 /* is_ip6 */ , 0);
 }
 
 /* *INDENT-OFF* */
@@ -509,7 +526,7 @@ VLIB_NODE_FN (esp6_encrypt_node) (vlib_main_t * vm,
                                  vlib_node_runtime_t * node,
                                  vlib_frame_t * from_frame)
 {
-  return esp_encrypt_inline (vm, node, from_frame, 1 /* is_ip6 */ );
+  return esp_encrypt_inline (vm, node, from_frame, 1 /* is_ip6 */ , 0);
 }
 
 /* *INDENT-OFF* */
@@ -531,6 +548,60 @@ VLIB_REGISTER_NODE (esp6_encrypt_node) = {
 };
 /* *INDENT-ON* */
 
+VLIB_NODE_FN (esp4_encrypt_tun_node) (vlib_main_t * vm,
+                                     vlib_node_runtime_t * node,
+                                     vlib_frame_t * from_frame)
+{
+  return esp_encrypt_inline (vm, node, from_frame, 0 /* is_ip6 */ , 1);
+}
+
+/* *INDENT-OFF* */
+VLIB_REGISTER_NODE (esp4_encrypt_tun_node) = {
+  .name = "esp4-encrypt-tun",
+  .vector_size = sizeof (u32),
+  .format_trace = format_esp_encrypt_trace,
+  .type = VLIB_NODE_TYPE_INTERNAL,
+
+  .n_errors = ARRAY_LEN(esp_encrypt_error_strings),
+  .error_strings = esp_encrypt_error_strings,
+};
+
+VNET_FEATURE_INIT (esp4_encrypt_tun_feat_node, static) =
+{
+  .arc_name = "ip4-output",
+  .node_name = "esp4-encrypt-tun",
+  .runs_before = VNET_FEATURES ("ip4-frag",
+                                "adj-midchain-tx"),
+};
+/* *INDENT-ON* */
+
+VLIB_NODE_FN (esp6_encrypt_tun_node) (vlib_main_t * vm,
+                                     vlib_node_runtime_t * node,
+                                     vlib_frame_t * from_frame)
+{
+  return esp_encrypt_inline (vm, node, from_frame, 1 /* is_ip6 */ , 1);
+}
+
+/* *INDENT-OFF* */
+VLIB_REGISTER_NODE (esp6_encrypt_tun_node) = {
+  .name = "esp6-encrypt-tun",
+  .vector_size = sizeof (u32),
+  .format_trace = format_esp_encrypt_trace,
+  .type = VLIB_NODE_TYPE_INTERNAL,
+
+  .n_errors = ARRAY_LEN(esp_encrypt_error_strings),
+  .error_strings = esp_encrypt_error_strings,
+};
+
+VNET_FEATURE_INIT (esp6_encrypt_tun_feat_node, static) =
+{
+  .arc_name = "ip6-output",
+  .node_name = "esp6-encrypt-tun",
+  .runs_before = VNET_FEATURES ("ip6-frag",
+                                "adj-midchain-tx"),
+};
+/* *INDENT-ON* */
+
 /*
  * fd.io coding-style-patch-verification: ON
  *