ipsec: esp-encrypt rework
[vpp.git] / src / vnet / ipsec / ipsec_sa.c
index 337ca34..3e29c04 100644 (file)
@@ -14,6 +14,8 @@
  */
 
 #include <vnet/ipsec/ipsec.h>
+#include <vnet/ipsec/esp.h>
+#include <vnet/udp/udp.h>
 #include <vnet/fib/fib_table.h>
 
 /**
@@ -97,6 +99,7 @@ ipsec_sa_set_crypto_alg (ipsec_sa_t * sa, ipsec_crypto_alg_t crypto_alg)
   sa->crypto_block_size = im->crypto_algs[crypto_alg].block_size;
   sa->crypto_enc_op_type = im->crypto_algs[crypto_alg].enc_op_type;
   sa->crypto_dec_op_type = im->crypto_algs[crypto_alg].dec_op_type;
+  ASSERT (sa->crypto_block_size <= ESP_MAX_BLOCK_SIZE);
 }
 
 void
@@ -106,6 +109,7 @@ ipsec_sa_set_integ_alg (ipsec_sa_t * sa, ipsec_integ_alg_t integ_alg)
   sa->integ_alg = integ_alg;
   sa->integ_trunc_size = im->integ_algs[integ_alg].trunc_size;
   sa->integ_op_type = im->integ_algs[integ_alg].op_type;
+  ASSERT (sa->integ_trunc_size <= ESP_MAX_ICV_SIZE);
 }
 
 int
@@ -199,7 +203,46 @@ ipsec_sa_add (u32 id,
       sa->sibling = fib_entry_child_add (sa->fib_entry_index,
                                         FIB_NODE_TYPE_IPSEC_SA, sa_index);
       ipsec_sa_stack (sa);
+
+      /* generate header templates */
+      if (sa->is_tunnel_ip6)
+       {
+         sa->ip6_hdr.ip_version_traffic_class_and_flow_label = 0x60;
+         sa->ip6_hdr.hop_limit = 254;
+         sa->ip6_hdr.src_address.as_u64[0] =
+           sa->tunnel_src_addr.ip6.as_u64[0];
+         sa->ip6_hdr.src_address.as_u64[1] =
+           sa->tunnel_src_addr.ip6.as_u64[1];
+         sa->ip6_hdr.dst_address.as_u64[0] =
+           sa->tunnel_dst_addr.ip6.as_u64[0];
+         sa->ip6_hdr.dst_address.as_u64[1] =
+           sa->tunnel_dst_addr.ip6.as_u64[1];
+         if (sa->udp_encap)
+           sa->ip6_hdr.protocol = IP_PROTOCOL_UDP;
+         else
+           sa->ip6_hdr.protocol = IP_PROTOCOL_IPSEC_ESP;
+       }
+      else
+       {
+         sa->ip4_hdr.ip_version_and_header_length = 0x45;
+         sa->ip4_hdr.ttl = 254;
+         sa->ip4_hdr.src_address.as_u32 = sa->tunnel_src_addr.ip4.as_u32;
+         sa->ip4_hdr.dst_address.as_u32 = sa->tunnel_dst_addr.ip4.as_u32;
+
+         if (sa->udp_encap)
+           sa->ip4_hdr.protocol = IP_PROTOCOL_UDP;
+         else
+           sa->ip4_hdr.protocol = IP_PROTOCOL_IPSEC_ESP;
+         sa->ip4_hdr.checksum = ip4_header_checksum (&sa->ip4_hdr);
+       }
     }
+
+  if (sa->udp_encap)
+    {
+      sa->udp_hdr.src_port = clib_host_to_net_u16 (UDP_DST_PORT_ipsec);
+      sa->udp_hdr.dst_port = clib_host_to_net_u16 (UDP_DST_PORT_ipsec);
+    }
+
   hash_set (im->sa_index_by_sa_id, sa->id, sa_index);
 
   if (sa_out_index)