aboutsummaryrefslogtreecommitdiffstats
path: root/src/vnet/ipsec/ipsec_sa.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/vnet/ipsec/ipsec_sa.c')
-rw-r--r--src/vnet/ipsec/ipsec_sa.c43
1 files changed, 43 insertions, 0 deletions
diff --git a/src/vnet/ipsec/ipsec_sa.c b/src/vnet/ipsec/ipsec_sa.c
index 337ca34eae9..3e29c0406e3 100644
--- a/src/vnet/ipsec/ipsec_sa.c
+++ b/src/vnet/ipsec/ipsec_sa.c
@@ -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)