diff options
Diffstat (limited to 'src/vnet/ipsec/ipsec_sa.c')
-rw-r--r-- | src/vnet/ipsec/ipsec_sa.c | 43 |
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) |