diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/plugins/dpdk/ipsec/esp_encrypt.c | 12 | ||||
-rw-r--r-- | src/plugins/ikev2/ikev2.c | 60 | ||||
-rw-r--r-- | src/vnet/ipsec/ah_encrypt.c | 71 | ||||
-rw-r--r-- | src/vnet/ipsec/esp_encrypt.c | 1 | ||||
-rw-r--r-- | src/vnet/ipsec/ipsec.api | 37 | ||||
-rw-r--r-- | src/vnet/ipsec/ipsec_api.c | 272 | ||||
-rw-r--r-- | src/vnet/ipsec/ipsec_cli.c | 27 | ||||
-rw-r--r-- | src/vnet/ipsec/ipsec_format.c | 22 | ||||
-rw-r--r-- | src/vnet/ipsec/ipsec_input.c | 8 | ||||
-rw-r--r-- | src/vnet/ipsec/ipsec_itf.c | 15 | ||||
-rw-r--r-- | src/vnet/ipsec/ipsec_sa.c | 98 | ||||
-rw-r--r-- | src/vnet/ipsec/ipsec_sa.h | 31 | ||||
-rw-r--r-- | src/vnet/ipsec/ipsec_tun.c | 14 | ||||
-rw-r--r-- | src/vnet/ipsec/ipsec_tun.h | 4 | ||||
-rw-r--r-- | src/vnet/ipsec/ipsec_types.api | 24 | ||||
-rw-r--r-- | src/vnet/tunnel/tunnel.c | 6 |
16 files changed, 410 insertions, 292 deletions
diff --git a/src/plugins/dpdk/ipsec/esp_encrypt.c b/src/plugins/dpdk/ipsec/esp_encrypt.c index 984bb64d1ef..f50291fcf2f 100644 --- a/src/plugins/dpdk/ipsec/esp_encrypt.c +++ b/src/plugins/dpdk/ipsec/esp_encrypt.c @@ -357,9 +357,9 @@ dpdk_esp_encrypt_inline (vlib_main_t * vm, clib_host_to_net_u32 (0xfe320000); oh0->ip4.src_address.as_u32 = - sa0->tunnel_src_addr.ip4.as_u32; + sa0->tunnel.t_src.ip.ip4.as_u32; oh0->ip4.dst_address.as_u32 = - sa0->tunnel_dst_addr.ip4.as_u32; + sa0->tunnel.t_dst.ip.ip4.as_u32; if (ipsec_sa_is_set_UDP_ENCAP (sa0)) { @@ -392,13 +392,13 @@ dpdk_esp_encrypt_inline (vlib_main_t * vm, oh6_0->ip6.protocol = IP_PROTOCOL_IPSEC_ESP; oh6_0->ip6.hop_limit = 254; oh6_0->ip6.src_address.as_u64[0] = - sa0->tunnel_src_addr.ip6.as_u64[0]; + sa0->tunnel.t_src.ip.ip6.as_u64[0]; oh6_0->ip6.src_address.as_u64[1] = - sa0->tunnel_src_addr.ip6.as_u64[1]; + sa0->tunnel.t_src.ip.ip6.as_u64[1]; oh6_0->ip6.dst_address.as_u64[0] = - sa0->tunnel_dst_addr.ip6.as_u64[0]; + sa0->tunnel.t_dst.ip.ip6.as_u64[0]; oh6_0->ip6.dst_address.as_u64[1] = - sa0->tunnel_dst_addr.ip6.as_u64[1]; + sa0->tunnel.t_dst.ip.ip6.as_u64[1]; esp0 = &oh6_0->esp; oh6_0->esp.spi = clib_host_to_net_u32 (sa0->spi); oh6_0->esp.seq = clib_host_to_net_u32 (sa0->seq); diff --git a/src/plugins/ikev2/ikev2.c b/src/plugins/ikev2/ikev2.c index aa57deb0924..0df7faa9bab 100644 --- a/src/plugins/ikev2/ikev2.c +++ b/src/plugins/ikev2/ikev2.c @@ -1823,8 +1823,8 @@ typedef struct u32 remote_spi; ipsec_crypto_alg_t encr_type; ipsec_integ_alg_t integ_type; - ip46_address_t local_ip; - ip46_address_t remote_ip; + ip_address_t local_ip; + ip_address_t remote_ip; ipsec_key_t loc_ckey, rem_ckey, loc_ikey, rem_ikey; u8 is_rekey; u32 old_remote_sa_id; @@ -1839,12 +1839,32 @@ ikev2_add_tunnel_from_main (ikev2_add_ipsec_tunnel_args_t * a) ikev2_main_t *km = &ikev2_main; u32 sw_if_index; int rv = 0; + tunnel_t tun_in = { + .t_flags = TUNNEL_FLAG_NONE, + .t_encap_decap_flags = TUNNEL_ENCAP_DECAP_FLAG_NONE, + .t_dscp = 0, + .t_mode = TUNNEL_MODE_P2P, + .t_table_id = 0, + .t_hop_limit = 255, + .t_src = a->local_ip, + .t_dst = a->remote_ip, + }; + tunnel_t tun_out = { + .t_flags = TUNNEL_FLAG_NONE, + .t_encap_decap_flags = TUNNEL_ENCAP_DECAP_FLAG_NONE, + .t_dscp = 0, + .t_mode = TUNNEL_MODE_P2P, + .t_table_id = 0, + .t_hop_limit = 255, + .t_src = a->remote_ip, + .t_dst = a->local_ip, + }; if (~0 == a->sw_if_index) { /* no tunnel associated with the SA/profile - create a new one */ - rv = ipip_add_tunnel (IPIP_TRANSPORT_IP4, ~0, - &a->local_ip, &a->remote_ip, 0, + rv = ipip_add_tunnel (IPIP_TRANSPORT_IP4, ~0, &ip_addr_46 (&a->local_ip), + &ip_addr_46 (&a->remote_ip), 0, TUNNEL_ENCAP_DECAP_FLAG_NONE, IP_DSCP_CS0, TUNNEL_MODE_P2P, &sw_if_index); @@ -1883,24 +1903,18 @@ ikev2_add_tunnel_from_main (ikev2_add_ipsec_tunnel_args_t * a) vec_add1 (sas_in, a->old_remote_sa_id); } - rv = ipsec_sa_add_and_lock (a->local_sa_id, - a->local_spi, - IPSEC_PROTOCOL_ESP, a->encr_type, - &a->loc_ckey, a->integ_type, &a->loc_ikey, - a->flags, 0, a->salt_local, &a->local_ip, - &a->remote_ip, TUNNEL_ENCAP_DECAP_FLAG_NONE, - IP_DSCP_CS0, NULL, a->src_port, a->dst_port); + rv = ipsec_sa_add_and_lock (a->local_sa_id, a->local_spi, IPSEC_PROTOCOL_ESP, + a->encr_type, &a->loc_ckey, a->integ_type, + &a->loc_ikey, a->flags, a->salt_local, + a->src_port, a->dst_port, &tun_out, NULL); if (rv) goto err0; - rv = ipsec_sa_add_and_lock (a->remote_sa_id, a->remote_spi, - IPSEC_PROTOCOL_ESP, a->encr_type, &a->rem_ckey, - a->integ_type, &a->rem_ikey, - (a->flags | IPSEC_SA_FLAG_IS_INBOUND), 0, - a->salt_remote, &a->remote_ip, - &a->local_ip, TUNNEL_ENCAP_DECAP_FLAG_NONE, - IP_DSCP_CS0, NULL, - a->ipsec_over_udp_port, a->ipsec_over_udp_port); + rv = ipsec_sa_add_and_lock ( + a->remote_sa_id, a->remote_spi, IPSEC_PROTOCOL_ESP, a->encr_type, + &a->rem_ckey, a->integ_type, &a->rem_ikey, + (a->flags | IPSEC_SA_FLAG_IS_INBOUND), a->salt_remote, + a->ipsec_over_udp_port, a->ipsec_over_udp_port, &tun_in, NULL); if (rv) goto err1; @@ -1944,16 +1958,16 @@ ikev2_create_tunnel_interface (vlib_main_t * vm, if (sa->is_initiator) { - ip_address_to_46 (&sa->iaddr, &a.local_ip); - ip_address_to_46 (&sa->raddr, &a.remote_ip); + ip_address_copy (&a.local_ip, &sa->iaddr); + ip_address_copy (&a.remote_ip, &sa->raddr); proposals = child->r_proposals; a.local_spi = child->r_proposals[0].spi; a.remote_spi = child->i_proposals[0].spi; } else { - ip_address_to_46 (&sa->raddr, &a.local_ip); - ip_address_to_46 (&sa->iaddr, &a.remote_ip); + ip_address_copy (&a.local_ip, &sa->raddr); + ip_address_copy (&a.remote_ip, &sa->iaddr); proposals = child->i_proposals; a.local_spi = child->i_proposals[0].spi; a.remote_spi = child->r_proposals[0].spi; diff --git a/src/vnet/ipsec/ah_encrypt.c b/src/vnet/ipsec/ah_encrypt.c index a4c34917550..610b95e8ce7 100644 --- a/src/vnet/ipsec/ah_encrypt.c +++ b/src/vnet/ipsec/ah_encrypt.c @@ -116,8 +116,8 @@ typedef struct * integrity check */ struct { - u8 hop_limit; u32 ip_version_traffic_class_and_flow_label; + u8 hop_limit; }; struct { @@ -125,8 +125,8 @@ typedef struct u8 tos; }; }; - i16 current_data; u8 skip; + i16 current_data; u32 sa_index; } ah_encrypt_packet_data_t; @@ -251,14 +251,14 @@ ah_encrypt_inline (vlib_main_t * vm, oh6_0->ip6.ip_version_traffic_class_and_flow_label = ih6_0->ip6.ip_version_traffic_class_and_flow_label; - ip6_set_dscp_network_order (&oh6_0->ip6, sa0->dscp); - - tunnel_encap_fixup_6o6 (sa0->tunnel_flags, - &ih6_0->ip6, &oh6_0->ip6); - + if (PREDICT_FALSE (ipsec_sa_is_set_IS_TUNNEL (sa0))) + { + ip6_set_dscp_network_order (&oh6_0->ip6, sa0->tunnel.t_dscp); + tunnel_encap_fixup_6o6 (sa0->tunnel_flags, &ih6_0->ip6, + &oh6_0->ip6); + } pd->ip_version_traffic_class_and_flow_label = oh6_0->ip6.ip_version_traffic_class_and_flow_label; - oh6_0->ip6.ip_version_traffic_class_and_flow_label = 0; if (PREDICT_TRUE (ipsec_sa_is_set_IS_TUNNEL (sa0))) { @@ -287,20 +287,27 @@ ah_encrypt_inline (vlib_main_t * vm, oh0 = vlib_buffer_get_current (b[0]); pd->ttl = ih0->ip4.ttl; - if (sa0->dscp) - pd->tos = sa0->dscp << 2; + if (PREDICT_FALSE (ipsec_sa_is_set_IS_TUNNEL (sa0))) + { + if (sa0->tunnel.t_dscp) + pd->tos = sa0->tunnel.t_dscp << 2; + else + { + pd->tos = ih0->ip4.tos; + + if (!(sa0->tunnel_flags & + TUNNEL_ENCAP_DECAP_FLAG_ENCAP_COPY_DSCP)) + pd->tos &= 0x3; + if (!(sa0->tunnel_flags & + TUNNEL_ENCAP_DECAP_FLAG_ENCAP_COPY_ECN)) + pd->tos &= 0xfc; + } + } else { pd->tos = ih0->ip4.tos; - if (! - (sa0->tunnel_flags & - TUNNEL_ENCAP_DECAP_FLAG_ENCAP_COPY_DSCP)) - pd->tos &= 0x3; - if (! - (sa0->tunnel_flags & - TUNNEL_ENCAP_DECAP_FLAG_ENCAP_COPY_ECN)) - pd->tos &= 0xfc; } + pd->current_data = b[0]->current_data; clib_memset (oh0, 0, sizeof (ip4_and_ah_header_t)); @@ -377,6 +384,18 @@ ah_encrypt_inline (vlib_main_t * vm, } next: + if (PREDICT_FALSE (b[0]->flags & VLIB_BUFFER_IS_TRACED)) + { + sa0 = vec_elt_at_index (im->sad, pd->sa_index); + ah_encrypt_trace_t *tr = + vlib_add_trace (vm, node, b[0], sizeof (*tr)); + tr->spi = sa0->spi; + tr->seq_lo = sa0->seq; + tr->seq_hi = sa0->seq_hi; + tr->integ_alg = sa0->integ_alg; + tr->sa_index = pd->sa_index; + } + n_left -= 1; next += 1; pd += 1; @@ -399,7 +418,7 @@ ah_encrypt_inline (vlib_main_t * vm, while (n_left) { if (pd->skip) - goto trace; + goto next_pkt; if (is_ip6) { @@ -416,19 +435,7 @@ ah_encrypt_inline (vlib_main_t * vm, oh0->ip4.checksum = ip4_header_checksum (&oh0->ip4); } - trace: - if (PREDICT_FALSE (b[0]->flags & VLIB_BUFFER_IS_TRACED)) - { - sa0 = vec_elt_at_index (im->sad, pd->sa_index); - ah_encrypt_trace_t *tr = - vlib_add_trace (vm, node, b[0], sizeof (*tr)); - tr->spi = sa0->spi; - tr->seq_lo = sa0->seq; - tr->seq_hi = sa0->seq_hi; - tr->integ_alg = sa0->integ_alg; - tr->sa_index = pd->sa_index; - } - + next_pkt: n_left -= 1; next += 1; pd += 1; diff --git a/src/vnet/ipsec/esp_encrypt.c b/src/vnet/ipsec/esp_encrypt.c index 08f82db5d58..e64de26327f 100644 --- a/src/vnet/ipsec/esp_encrypt.c +++ b/src/vnet/ipsec/esp_encrypt.c @@ -829,6 +829,7 @@ esp_encrypt_inline (vlib_main_t *vm, vlib_node_runtime_t *node, } else next[0] = ESP_ENCRYPT_NEXT_INTERFACE_OUTPUT; + b[0]->flags |= VNET_BUFFER_F_LOCALLY_ORIGINATED; } else /* transport mode */ { diff --git a/src/vnet/ipsec/ipsec.api b/src/vnet/ipsec/ipsec.api index c009d8dffaa..8d4580a2c28 100644 --- a/src/vnet/ipsec/ipsec.api +++ b/src/vnet/ipsec/ipsec.api @@ -14,7 +14,7 @@ * limitations under the License. */ -option version = "5.0.0"; +option version = "5.0.1"; import "vnet/ipsec/ipsec_types.api"; import "vnet/interface_types.api"; @@ -191,6 +191,7 @@ define ipsec_spd_details { */ define ipsec_sad_entry_add_del { + option deprecated; u32 client_index; u32 context; bool is_add; @@ -203,8 +204,17 @@ define ipsec_sad_entry_add_del_v2 bool is_add; vl_api_ipsec_sad_entry_v2_t entry; }; +define ipsec_sad_entry_add_del_v3 +{ + u32 client_index; + u32 context; + bool is_add; + vl_api_ipsec_sad_entry_v3_t entry; +}; + define ipsec_sad_entry_add_del_reply { + option deprecated; u32 context; i32 retval; u32 stat_index; @@ -215,6 +225,12 @@ define ipsec_sad_entry_add_del_v2_reply i32 retval; u32 stat_index; }; +define ipsec_sad_entry_add_del_v3_reply +{ + u32 context; + i32 retval; + u32 stat_index; +}; /** \brief Add or Update Protection for a tunnel with IPSEC @@ -378,6 +394,7 @@ define ipsec_itf_details */ define ipsec_sa_dump { + option deprecated; u32 client_index; u32 context; u32 sa_id; @@ -388,6 +405,12 @@ define ipsec_sa_v2_dump u32 context; u32 sa_id; }; +define ipsec_sa_v3_dump +{ + u32 client_index; + u32 context; + u32 sa_id; +}; /** \brief IPsec security association database response @param context - sender context which was passed in the request @@ -402,6 +425,7 @@ define ipsec_sa_v2_dump @param stat_index - index for the SA in the stats segment @ /net/ipsec/sa */ define ipsec_sa_details { + option deprecated; u32 context; vl_api_ipsec_sad_entry_t entry; @@ -425,6 +449,17 @@ define ipsec_sa_v2_details { u32 stat_index; }; +define ipsec_sa_v3_details { + u32 context; + vl_api_ipsec_sad_entry_v3_t entry; + + vl_api_interface_index_t sw_if_index; + u64 seq_outbound; + u64 last_seq_inbound; + u64 replay_window; + + u32 stat_index; +}; /** \brief Dump IPsec backends @param client_index - opaque cookie to identify the sender diff --git a/src/vnet/ipsec/ipsec_api.c b/src/vnet/ipsec/ipsec_api.c index 1a419e5c21a..a3e0545c1b5 100644 --- a/src/vnet/ipsec/ipsec_api.c +++ b/src/vnet/ipsec/ipsec_api.c @@ -54,26 +54,28 @@ #include <vlibapi/api_helper_macros.h> -#define foreach_vpe_api_msg \ -_(IPSEC_SPD_ADD_DEL, ipsec_spd_add_del) \ -_(IPSEC_INTERFACE_ADD_DEL_SPD, ipsec_interface_add_del_spd) \ -_(IPSEC_SPD_ENTRY_ADD_DEL, ipsec_spd_entry_add_del) \ -_(IPSEC_SAD_ENTRY_ADD_DEL, ipsec_sad_entry_add_del) \ -_(IPSEC_SAD_ENTRY_ADD_DEL_V2, ipsec_sad_entry_add_del_v2) \ -_(IPSEC_SA_DUMP, ipsec_sa_dump) \ -_(IPSEC_SA_V2_DUMP, ipsec_sa_v2_dump) \ -_(IPSEC_SPDS_DUMP, ipsec_spds_dump) \ -_(IPSEC_SPD_DUMP, ipsec_spd_dump) \ -_(IPSEC_SPD_INTERFACE_DUMP, ipsec_spd_interface_dump) \ -_(IPSEC_ITF_CREATE, ipsec_itf_create) \ -_(IPSEC_ITF_DELETE, ipsec_itf_delete) \ -_(IPSEC_ITF_DUMP, ipsec_itf_dump) \ -_(IPSEC_SELECT_BACKEND, ipsec_select_backend) \ -_(IPSEC_BACKEND_DUMP, ipsec_backend_dump) \ -_(IPSEC_TUNNEL_PROTECT_UPDATE, ipsec_tunnel_protect_update) \ -_(IPSEC_TUNNEL_PROTECT_DEL, ipsec_tunnel_protect_del) \ -_(IPSEC_TUNNEL_PROTECT_DUMP, ipsec_tunnel_protect_dump) \ -_(IPSEC_SET_ASYNC_MODE, ipsec_set_async_mode) +#define foreach_vpe_api_msg \ + _ (IPSEC_SPD_ADD_DEL, ipsec_spd_add_del) \ + _ (IPSEC_INTERFACE_ADD_DEL_SPD, ipsec_interface_add_del_spd) \ + _ (IPSEC_SPD_ENTRY_ADD_DEL, ipsec_spd_entry_add_del) \ + _ (IPSEC_SAD_ENTRY_ADD_DEL, ipsec_sad_entry_add_del) \ + _ (IPSEC_SAD_ENTRY_ADD_DEL_V2, ipsec_sad_entry_add_del_v2) \ + _ (IPSEC_SAD_ENTRY_ADD_DEL_V3, ipsec_sad_entry_add_del_v3) \ + _ (IPSEC_SA_DUMP, ipsec_sa_dump) \ + _ (IPSEC_SA_V2_DUMP, ipsec_sa_v2_dump) \ + _ (IPSEC_SA_V3_DUMP, ipsec_sa_v3_dump) \ + _ (IPSEC_SPDS_DUMP, ipsec_spds_dump) \ + _ (IPSEC_SPD_DUMP, ipsec_spd_dump) \ + _ (IPSEC_SPD_INTERFACE_DUMP, ipsec_spd_interface_dump) \ + _ (IPSEC_ITF_CREATE, ipsec_itf_create) \ + _ (IPSEC_ITF_DELETE, ipsec_itf_delete) \ + _ (IPSEC_ITF_DUMP, ipsec_itf_dump) \ + _ (IPSEC_SELECT_BACKEND, ipsec_select_backend) \ + _ (IPSEC_BACKEND_DUMP, ipsec_backend_dump) \ + _ (IPSEC_TUNNEL_PROTECT_UPDATE, ipsec_tunnel_protect_update) \ + _ (IPSEC_TUNNEL_PROTECT_DEL, ipsec_tunnel_protect_del) \ + _ (IPSEC_TUNNEL_PROTECT_DUMP, ipsec_tunnel_protect_dump) \ + _ (IPSEC_SET_ASYNC_MODE, ipsec_set_async_mode) static void vl_api_ipsec_spd_add_del_t_handler (vl_api_ipsec_spd_add_del_t * mp) @@ -335,17 +337,21 @@ out: static void vl_api_ipsec_sad_entry_add_del_t_handler (vl_api_ipsec_sad_entry_add_del_t * mp) { - vlib_main_t *vm __attribute__ ((unused)) = vlib_get_main (); vl_api_ipsec_sad_entry_add_del_reply_t *rmp; - ip46_address_t tun_src = { }, tun_dst = - { - }; ipsec_key_t crypto_key, integ_key; ipsec_crypto_alg_t crypto_alg; ipsec_integ_alg_t integ_alg; ipsec_protocol_t proto; ipsec_sa_flags_t flags; u32 id, spi, sa_index = ~0; + tunnel_t tun = { + .t_flags = TUNNEL_FLAG_NONE, + .t_encap_decap_flags = TUNNEL_ENCAP_DECAP_FLAG_NONE, + .t_dscp = 0, + .t_mode = TUNNEL_MODE_P2P, + .t_table_id = 0, + .t_hop_limit = 255, + }; int rv; #if WITH_LIBSSL > 0 @@ -373,19 +379,14 @@ static void vl_api_ipsec_sad_entry_add_del_t_handler flags = ipsec_sa_flags_decode (mp->entry.flags); - ip_address_decode (&mp->entry.tunnel_src, &tun_src); - ip_address_decode (&mp->entry.tunnel_dst, &tun_dst); + ip_address_decode2 (&mp->entry.tunnel_src, &tun.t_src); + ip_address_decode2 (&mp->entry.tunnel_dst, &tun.t_dst); if (mp->is_add) - rv = ipsec_sa_add_and_lock (id, spi, proto, - crypto_alg, &crypto_key, - integ_alg, &integ_key, flags, - 0, mp->entry.salt, &tun_src, &tun_dst, - TUNNEL_ENCAP_DECAP_FLAG_NONE, - IP_DSCP_CS0, - &sa_index, - htons (mp->entry.udp_src_port), - htons (mp->entry.udp_dst_port)); + rv = ipsec_sa_add_and_lock ( + id, spi, proto, crypto_alg, &crypto_key, integ_alg, &integ_key, flags, + mp->entry.salt, htons (mp->entry.udp_src_port), + htons (mp->entry.udp_dst_port), &tun, &sa_index); else rv = ipsec_sa_unlock_id (id); @@ -407,10 +408,6 @@ static void vl_api_ipsec_sad_entry_add_del_v2_t_handler { vlib_main_t *vm __attribute__ ((unused)) = vlib_get_main (); vl_api_ipsec_sad_entry_add_del_v2_reply_t *rmp; - ip46_address_t tun_src = { }, tun_dst = - { - }; - tunnel_encap_decap_flags_t tunnel_flags; ipsec_key_t crypto_key, integ_key; ipsec_crypto_alg_t crypto_alg; ipsec_integ_alg_t integ_alg; @@ -418,6 +415,14 @@ static void vl_api_ipsec_sad_entry_add_del_v2_t_handler ipsec_sa_flags_t flags; u32 id, spi, sa_index = ~0; int rv; + tunnel_t tun = { + .t_flags = TUNNEL_FLAG_NONE, + .t_encap_decap_flags = TUNNEL_ENCAP_DECAP_FLAG_NONE, + .t_dscp = 0, + .t_mode = TUNNEL_MODE_P2P, + .t_table_id = htonl (mp->entry.tx_table_id), + .t_hop_limit = 255, + }; #if WITH_LIBSSL > 0 @@ -439,8 +444,8 @@ static void vl_api_ipsec_sad_entry_add_del_v2_t_handler if (rv) goto out; - rv = - tunnel_encap_decap_flags_decode (mp->entry.tunnel_flags, &tunnel_flags); + rv = tunnel_encap_decap_flags_decode (mp->entry.tunnel_flags, + &tun.t_encap_decap_flags); if (rv) goto out; @@ -449,16 +454,16 @@ static void vl_api_ipsec_sad_entry_add_del_v2_t_handler ipsec_key_decode (&mp->entry.integrity_key, &integ_key); flags = ipsec_sa_flags_decode (mp->entry.flags); + tun.t_dscp = ip_dscp_decode (mp->entry.dscp); - ip_address_decode (&mp->entry.tunnel_src, &tun_src); - ip_address_decode (&mp->entry.tunnel_dst, &tun_dst); + ip_address_decode2 (&mp->entry.tunnel_src, &tun.t_src); + ip_address_decode2 (&mp->entry.tunnel_dst, &tun.t_dst); if (mp->is_add) rv = ipsec_sa_add_and_lock ( id, spi, proto, crypto_alg, &crypto_key, integ_alg, &integ_key, flags, - htonl (mp->entry.tx_table_id), mp->entry.salt, &tun_src, &tun_dst, - tunnel_flags, ip_dscp_decode (mp->entry.dscp), &sa_index, - htons (mp->entry.udp_src_port), htons (mp->entry.udp_dst_port)); + mp->entry.salt, htons (mp->entry.udp_src_port), + htons (mp->entry.udp_dst_port), &tun, &sa_index); else rv = ipsec_sa_unlock_id (id); @@ -476,6 +481,70 @@ out: } static void +vl_api_ipsec_sad_entry_add_del_v3_t_handler ( + vl_api_ipsec_sad_entry_add_del_v3_t *mp) +{ + vl_api_ipsec_sad_entry_add_del_v3_reply_t *rmp; + ipsec_key_t crypto_key, integ_key; + ipsec_crypto_alg_t crypto_alg; + ipsec_integ_alg_t integ_alg; + ipsec_protocol_t proto; + ipsec_sa_flags_t flags; + u32 id, spi, sa_index = ~0; + tunnel_t tun; + int rv; + +#if WITH_LIBSSL > 0 + + id = ntohl (mp->entry.sad_id); + spi = ntohl (mp->entry.spi); + + rv = ipsec_proto_decode (mp->entry.protocol, &proto); + + if (rv) + goto out; + + rv = ipsec_crypto_algo_decode (mp->entry.crypto_algorithm, &crypto_alg); + + if (rv) + goto out; + + rv = ipsec_integ_algo_decode (mp->entry.integrity_algorithm, &integ_alg); + + if (rv) + goto out; + + flags = ipsec_sa_flags_decode (mp->entry.flags); + + if (flags & IPSEC_SA_FLAG_IS_TUNNEL) + { + rv = tunnel_decode (&mp->entry.tunnel, &tun); + + if (rv) + goto out; + } + + ipsec_key_decode (&mp->entry.crypto_key, &crypto_key); + ipsec_key_decode (&mp->entry.integrity_key, &integ_key); + + if (mp->is_add) + rv = ipsec_sa_add_and_lock ( + id, spi, proto, crypto_alg, &crypto_key, integ_alg, &integ_key, flags, + mp->entry.salt, htons (mp->entry.udp_src_port), + htons (mp->entry.udp_dst_port), &tun, &sa_index); + else + rv = ipsec_sa_unlock_id (id); + +#else + rv = VNET_API_ERROR_UNIMPLEMENTED; +#endif + +out: + REPLY_MACRO2 (VL_API_IPSEC_SAD_ENTRY_ADD_DEL_V3_REPLY, + { rmp->stat_index = htonl (sa_index); }); +} + +static void send_ipsec_spds_details (ipsec_spd_t * spd, vl_api_registration_t * reg, u32 context) { @@ -746,8 +815,7 @@ send_ipsec_sa_details (ipsec_sa_t * sa, void *arg) mp->entry.sad_id = htonl (sa->id); mp->entry.spi = htonl (sa->spi); mp->entry.protocol = ipsec_proto_encode (sa->protocol); - mp->entry.tx_table_id = - htonl (fib_table_get_table_id (sa->tx_fib_index, FIB_PROTOCOL_IP4)); + mp->entry.tx_table_id = htonl (sa->tunnel.t_table_id); mp->entry.crypto_algorithm = ipsec_crypto_algo_encode (sa->crypto_alg); ipsec_key_encode (&sa->crypto_key, &mp->entry.crypto_key); @@ -773,10 +841,8 @@ send_ipsec_sa_details (ipsec_sa_t * sa, void *arg) if (ipsec_sa_is_set_IS_TUNNEL (sa)) { - ip_address_encode (&sa->tunnel_src_addr, IP46_TYPE_ANY, - &mp->entry.tunnel_src); - ip_address_encode (&sa->tunnel_dst_addr, IP46_TYPE_ANY, - &mp->entry.tunnel_dst); + ip_address_encode2 (&sa->tunnel.t_src, &mp->entry.tunnel_src); + ip_address_encode2 (&sa->tunnel.t_dst, &mp->entry.tunnel_dst); } if (ipsec_sa_is_set_UDP_ENCAP (sa)) { @@ -838,8 +904,7 @@ send_ipsec_sa_v2_details (ipsec_sa_t * sa, void *arg) mp->entry.sad_id = htonl (sa->id); mp->entry.spi = htonl (sa->spi); mp->entry.protocol = ipsec_proto_encode (sa->protocol); - mp->entry.tx_table_id = - htonl (fib_table_get_table_id (sa->tx_fib_index, FIB_PROTOCOL_IP4)); + mp->entry.tx_table_id = htonl (sa->tunnel.t_table_id); mp->entry.crypto_algorithm = ipsec_crypto_algo_encode (sa->crypto_alg); ipsec_key_encode (&sa->crypto_key, &mp->entry.crypto_key); @@ -865,10 +930,8 @@ send_ipsec_sa_v2_details (ipsec_sa_t * sa, void *arg) if (ipsec_sa_is_set_IS_TUNNEL (sa)) { - ip_address_encode (&sa->tunnel_src_addr, IP46_TYPE_ANY, - &mp->entry.tunnel_src); - ip_address_encode (&sa->tunnel_dst_addr, IP46_TYPE_ANY, - &mp->entry.tunnel_dst); + ip_address_encode2 (&sa->tunnel.t_src, &mp->entry.tunnel_src); + ip_address_encode2 (&sa->tunnel.t_dst, &mp->entry.tunnel_dst); } if (ipsec_sa_is_set_UDP_ENCAP (sa)) { @@ -876,8 +939,9 @@ send_ipsec_sa_v2_details (ipsec_sa_t * sa, void *arg) mp->entry.udp_dst_port = sa->udp_hdr.dst_port; } - mp->entry.tunnel_flags = tunnel_encap_decap_flags_encode (sa->tunnel_flags); - mp->entry.dscp = ip_dscp_encode (sa->dscp); + mp->entry.tunnel_flags = + tunnel_encap_decap_flags_encode (sa->tunnel.t_encap_decap_flags); + mp->entry.dscp = ip_dscp_encode (sa->tunnel.t_dscp); mp->seq_outbound = clib_host_to_net_u64 (((u64) sa->seq)); mp->last_seq_inbound = clib_host_to_net_u64 (((u64) sa->last_seq)); @@ -897,7 +961,7 @@ send_ipsec_sa_v2_details (ipsec_sa_t * sa, void *arg) } static void -vl_api_ipsec_sa_v2_dump_t_handler (vl_api_ipsec_sa_dump_t * mp) +vl_api_ipsec_sa_v2_dump_t_handler (vl_api_ipsec_sa_v2_dump_t *mp) { vl_api_registration_t *reg; @@ -918,6 +982,92 @@ vl_api_ipsec_sa_v2_dump_t_handler (vl_api_ipsec_sa_dump_t * mp) #endif } +static walk_rc_t +send_ipsec_sa_v3_details (ipsec_sa_t *sa, void *arg) +{ + ipsec_dump_walk_ctx_t *ctx = arg; + vl_api_ipsec_sa_v3_details_t *mp; + ipsec_main_t *im = &ipsec_main; + + mp = vl_msg_api_alloc (sizeof (*mp)); + clib_memset (mp, 0, sizeof (*mp)); + mp->_vl_msg_id = ntohs (VL_API_IPSEC_SA_V3_DETAILS); + mp->context = ctx->context; + + mp->entry.sad_id = htonl (sa->id); + mp->entry.spi = htonl (sa->spi); + mp->entry.protocol = ipsec_proto_encode (sa->protocol); + + mp->entry.crypto_algorithm = ipsec_crypto_algo_encode (sa->crypto_alg); + ipsec_key_encode (&sa->crypto_key, &mp->entry.crypto_key); + + mp->entry.integrity_algorithm = ipsec_integ_algo_encode (sa->integ_alg); + ipsec_key_encode (&sa->integ_key, &mp->entry.integrity_key); + + mp->entry.flags = ipsec_sad_flags_encode (sa); + mp->entry.salt = clib_host_to_net_u32 (sa->salt); + + if (ipsec_sa_is_set_IS_PROTECT (sa)) + { + ipsec_sa_dump_match_ctx_t ctx = { + .sai = sa - im->sad, + .sw_if_index = ~0, + }; + ipsec_tun_protect_walk (ipsec_sa_dump_match_sa, &ctx); + + mp->sw_if_index = htonl (ctx.sw_if_index); + } + else + mp->sw_if_index = ~0; + + if (ipsec_sa_is_set_IS_TUNNEL (sa)) + tunnel_encode (&sa->tunnel, &mp->entry.tunnel); + + if (ipsec_sa_is_set_UDP_ENCAP (sa)) + { + mp->entry.udp_src_port = sa->udp_hdr.src_port; + mp->entry.udp_dst_port = sa->udp_hdr.dst_port; + } + + mp->seq_outbound = clib_host_to_net_u64 (((u64) sa->seq)); + mp->last_seq_inbound = clib_host_to_net_u64 (((u64) sa->last_seq)); + if (ipsec_sa_is_set_USE_ESN (sa)) + { + mp->seq_outbound |= (u64) (clib_host_to_net_u32 (sa->seq_hi)); + mp->last_seq_inbound |= (u64) (clib_host_to_net_u32 (sa->last_seq_hi)); + } + if (ipsec_sa_is_set_USE_ANTI_REPLAY (sa)) + mp->replay_window = clib_host_to_net_u64 (sa->replay_window); + + mp->stat_index = clib_host_to_net_u32 (sa->stat_index); + + vl_api_send_msg (ctx->reg, (u8 *) mp); + + return (WALK_CONTINUE); +} + +static void +vl_api_ipsec_sa_v3_dump_t_handler (vl_api_ipsec_sa_v3_dump_t *mp) +{ + vl_api_registration_t *reg; + +#if WITH_LIBSSL > 0 + reg = vl_api_client_index_to_registration (mp->client_index); + if (!reg) + return; + + ipsec_dump_walk_ctx_t ctx = { + .reg = reg, + .context = mp->context, + }; + + ipsec_sa_walk (send_ipsec_sa_v3_details, &ctx); + +#else + clib_warning ("unimplemented"); +#endif +} + static void vl_api_ipsec_backend_dump_t_handler (vl_api_ipsec_backend_dump_t * mp) { diff --git a/src/vnet/ipsec/ipsec_cli.c b/src/vnet/ipsec/ipsec_cli.c index b708e50378c..eed910edb93 100644 --- a/src/vnet/ipsec/ipsec_cli.c +++ b/src/vnet/ipsec/ipsec_cli.c @@ -86,9 +86,6 @@ ipsec_sa_add_del_command_fn (vlib_main_t * vm, vlib_cli_command_t * cmd) { unformat_input_t _line_input, *line_input = &_line_input; - ip46_address_t tun_src = { }, tun_dst = - { - }; ipsec_crypto_alg_t crypto_alg; ipsec_integ_alg_t integ_alg; ipsec_protocol_t proto; @@ -101,8 +98,7 @@ ipsec_sa_add_del_command_fn (vlib_main_t * vm, u16 udp_src, udp_dst; int is_add, rv; u32 m_args = 0; - ip_dscp_t dscp; - u32 tx_table_id; + tunnel_t tun; salt = 0; error = NULL; @@ -112,8 +108,6 @@ ipsec_sa_add_del_command_fn (vlib_main_t * vm, integ_alg = IPSEC_INTEG_ALG_NONE; crypto_alg = IPSEC_CRYPTO_ALG_NONE; udp_src = udp_dst = IPSEC_UDP_PORT_NONE; - dscp = IP_DSCP_CS0; - tx_table_id = 0; if (!unformat_user (input, unformat_line_input, line_input)) return 0; @@ -149,22 +143,16 @@ ipsec_sa_add_del_command_fn (vlib_main_t * vm, else if (unformat (line_input, "integ-alg %U", unformat_ipsec_integ_alg, &integ_alg)) ; - else if (unformat (line_input, "tunnel-src %U", - unformat_ip46_address, &tun_src, IP46_TYPE_ANY)) + else if (unformat (line_input, " %U", unformat_tunnel, &tun)) { flags |= IPSEC_SA_FLAG_IS_TUNNEL; - if (!ip46_address_is_ip4 (&tun_src)) + if (AF_IP6 == tunnel_get_af (&tun)) flags |= IPSEC_SA_FLAG_IS_TUNNEL_V6; } - else if (unformat (line_input, "tunnel-dst %U", - unformat_ip46_address, &tun_dst, IP46_TYPE_ANY)) - ; else if (unformat (line_input, "udp-src-port %d", &i)) udp_src = i; else if (unformat (line_input, "udp-dst-port %d", &i)) udp_dst = i; - else if (unformat (line_input, "tx-table-id %d", &tx_table_id)) - ; else if (unformat (line_input, "inbound")) flags |= IPSEC_SA_FLAG_IS_INBOUND; else if (unformat (line_input, "use-anti-replay")) @@ -200,12 +188,9 @@ ipsec_sa_add_del_command_fn (vlib_main_t * vm, error = clib_error_return (0, "missing spi"); goto done; } - rv = ipsec_sa_add_and_lock (id, spi, proto, crypto_alg, - &ck, integ_alg, &ik, flags, - tx_table_id, clib_host_to_net_u32 (salt), - &tun_src, &tun_dst, - TUNNEL_ENCAP_DECAP_FLAG_NONE, dscp, - &sai, udp_src, udp_dst); + rv = ipsec_sa_add_and_lock (id, spi, proto, crypto_alg, &ck, integ_alg, + &ik, flags, clib_host_to_net_u32 (salt), + udp_src, udp_dst, &tun, &sai); } else { diff --git a/src/vnet/ipsec/ipsec_format.c b/src/vnet/ipsec/ipsec_format.c index 19321e7e347..001aa010364 100644 --- a/src/vnet/ipsec/ipsec_format.c +++ b/src/vnet/ipsec/ipsec_format.c @@ -273,7 +273,6 @@ format_ipsec_sa (u8 * s, va_list * args) ipsec_format_flags_t flags = va_arg (*args, ipsec_format_flags_t); ipsec_main_t *im = &ipsec_main; vlib_counter_t counts; - u32 tx_table_id; ipsec_sa_t *sa; if (pool_is_free_index (im->sad, sai)) @@ -318,26 +317,7 @@ format_ipsec_sa (u8 * s, va_list * args) s = format (s, "\n packets %u bytes %u", counts.packets, counts.bytes); if (ipsec_sa_is_set_IS_TUNNEL (sa)) - { - tx_table_id = fib_table_get_table_id ( - sa->tx_fib_index, - (ipsec_sa_is_set_IS_TUNNEL_V6 (sa) ? FIB_PROTOCOL_IP6 : - FIB_PROTOCOL_IP4)); - s = format (s, "\n table-ID %d tunnel %U src %U dst %U flags %U", - tx_table_id, - format_ip_dscp, sa->dscp, - format_ip46_address, &sa->tunnel_src_addr, IP46_TYPE_ANY, - format_ip46_address, &sa->tunnel_dst_addr, IP46_TYPE_ANY, - format_tunnel_encap_decap_flags, sa->tunnel_flags); - if (!ipsec_sa_is_set_IS_INBOUND (sa)) - { - s = - format (s, "\n resovle via fib-entry: %d", - sa->fib_entry_index); - s = format (s, "\n stacked on:"); - s = format (s, "\n %U", format_dpo_id, &sa->dpo, 6); - } - } + s = format (s, "\n%U", format_tunnel, &sa->tunnel, 3); done: return (s); diff --git a/src/vnet/ipsec/ipsec_input.c b/src/vnet/ipsec/ipsec_input.c index aa7627d9b4b..2ebc6c5a10c 100644 --- a/src/vnet/ipsec/ipsec_input.c +++ b/src/vnet/ipsec/ipsec_input.c @@ -118,10 +118,10 @@ ipsec_input_protect_policy_match (ipsec_spd_t * spd, u32 sa, u32 da, u32 spi) if (ipsec_sa_is_set_IS_TUNNEL (s)) { - if (da != clib_net_to_host_u32 (s->tunnel_dst_addr.ip4.as_u32)) + if (da != clib_net_to_host_u32 (s->tunnel.t_dst.ip.ip4.as_u32)) continue; - if (sa != clib_net_to_host_u32 (s->tunnel_src_addr.ip4.as_u32)) + if (sa != clib_net_to_host_u32 (s->tunnel.t_src.ip.ip4.as_u32)) continue; return p; @@ -174,10 +174,10 @@ ipsec6_input_protect_policy_match (ipsec_spd_t * spd, if (ipsec_sa_is_set_IS_TUNNEL (s)) { - if (!ip6_address_is_equal (sa, &s->tunnel_src_addr.ip6)) + if (!ip6_address_is_equal (sa, &s->tunnel.t_src.ip.ip6)) continue; - if (!ip6_address_is_equal (da, &s->tunnel_dst_addr.ip6)) + if (!ip6_address_is_equal (da, &s->tunnel.t_dst.ip.ip6)) continue; return p; diff --git a/src/vnet/ipsec/ipsec_itf.c b/src/vnet/ipsec/ipsec_itf.c index 4a0f9e7bb6c..5f04fcf0a04 100644 --- a/src/vnet/ipsec/ipsec_itf.c +++ b/src/vnet/ipsec/ipsec_itf.c @@ -70,20 +70,11 @@ ipsec_itf_adj_stack (adj_index_t ai, u32 sai) if (hw->flags & VNET_HW_INTERFACE_FLAG_LINK_UP) { const ipsec_sa_t *sa; + fib_prefix_t dst; sa = ipsec_sa_get (sai); - - /* *INDENT-OFF* */ - const fib_prefix_t dst = { - .fp_len = (ipsec_sa_is_set_IS_TUNNEL_V6(sa) ? 128 : 32), - .fp_proto = (ipsec_sa_is_set_IS_TUNNEL_V6(sa)? - FIB_PROTOCOL_IP6 : - FIB_PROTOCOL_IP4), - .fp_addr = sa->tunnel_dst_addr, - }; - /* *INDENT-ON* */ - - adj_midchain_delegate_stack (ai, sa->tx_fib_index, &dst); + ip_address_to_fib_prefix (&sa->tunnel.t_dst, &dst); + adj_midchain_delegate_stack (ai, sa->tunnel.t_fib_index, &dst); } else adj_midchain_delegate_unstack (ai); diff --git a/src/vnet/ipsec/ipsec_sa.c b/src/vnet/ipsec/ipsec_sa.c index 515eb25d323..0a24aa2c8c0 100644 --- a/src/vnet/ipsec/ipsec_sa.c +++ b/src/vnet/ipsec/ipsec_sa.c @@ -72,15 +72,9 @@ static void ipsec_sa_stack (ipsec_sa_t * sa) { ipsec_main_t *im = &ipsec_main; - fib_forward_chain_type_t fct; dpo_id_t tmp = DPO_INVALID; - fct = - fib_forw_chain_type_from_fib_proto ((ipsec_sa_is_set_IS_TUNNEL_V6 (sa) ? - FIB_PROTOCOL_IP6 : - FIB_PROTOCOL_IP4)); - - fib_entry_contribute_forwarding (sa->fib_entry_index, fct, &tmp); + tunnel_contribute_forwarding (&sa->tunnel, &tmp); if (IPSEC_PROTOCOL_AH == sa->protocol) dpo_stack_from_node ((ipsec_sa_is_set_IS_TUNNEL_V6 (sa) ? @@ -172,21 +166,11 @@ ipsec_sa_set_async_op_ids (ipsec_sa_t * sa) } int -ipsec_sa_add_and_lock (u32 id, - u32 spi, - ipsec_protocol_t proto, - ipsec_crypto_alg_t crypto_alg, - const ipsec_key_t * ck, - ipsec_integ_alg_t integ_alg, - const ipsec_key_t * ik, - ipsec_sa_flags_t flags, - u32 tx_table_id, - u32 salt, - const ip46_address_t * tun_src, - const ip46_address_t * tun_dst, - tunnel_encap_decap_flags_t tunnel_flags, - ip_dscp_t dscp, - u32 * sa_out_index, u16 src_port, u16 dst_port) +ipsec_sa_add_and_lock (u32 id, u32 spi, ipsec_protocol_t proto, + ipsec_crypto_alg_t crypto_alg, const ipsec_key_t *ck, + ipsec_integ_alg_t integ_alg, const ipsec_key_t *ik, + ipsec_sa_flags_t flags, u32 salt, u16 src_port, + u16 dst_port, const tunnel_t *tun, u32 *sa_out_index) { vlib_main_t *vm = vlib_get_main (); ipsec_main_t *im = &ipsec_main; @@ -194,6 +178,7 @@ ipsec_sa_add_and_lock (u32 id, ipsec_sa_t *sa; u32 sa_index; uword *p; + int rv; p = hash_get (im->sa_index_by_sa_id, id); if (p) @@ -208,13 +193,12 @@ ipsec_sa_add_and_lock (u32 id, vlib_validate_combined_counter (&ipsec_sa_counters, sa_index); vlib_zero_combined_counter (&ipsec_sa_counters, sa_index); + tunnel_copy (tun, &sa->tunnel); sa->id = id; sa->spi = spi; sa->stat_index = sa_index; sa->protocol = proto; sa->flags = flags; - sa->tunnel_flags = tunnel_flags; - sa->dscp = dscp; sa->salt = salt; sa->thread_index = (vlib_num_workers ()) ? ~0 : 0; if (integ_alg != IPSEC_INTEG_ALG_NONE) @@ -226,8 +210,6 @@ ipsec_sa_add_and_lock (u32 id, ipsec_sa_set_async_op_ids (sa); clib_memcpy (&sa->crypto_key, ck, sizeof (sa->crypto_key)); - ip46_address_copy (&sa->tunnel_src_addr, tun_src); - ip46_address_copy (&sa->tunnel_dst_addr, tun_dst); sa->crypto_key_index = vnet_crypto_key_add (vm, im->crypto_algs[crypto_alg].alg, @@ -281,59 +263,33 @@ ipsec_sa_add_and_lock (u32 id, if (ipsec_sa_is_set_IS_TUNNEL (sa) && !ipsec_sa_is_set_IS_INBOUND (sa)) { - fib_protocol_t fproto = (ipsec_sa_is_set_IS_TUNNEL_V6 (sa) ? - FIB_PROTOCOL_IP6 : FIB_PROTOCOL_IP4); - fib_prefix_t pfx = { - .fp_addr = sa->tunnel_dst_addr, - .fp_len = (ipsec_sa_is_set_IS_TUNNEL_V6 (sa) ? 128 : 32), - .fp_proto = fproto, - }; - sa->tx_fib_index = fib_table_find (fproto, tx_table_id); - if (sa->tx_fib_index == ~((u32) 0)) + sa->tunnel_flags = sa->tunnel.t_encap_decap_flags; + + rv = tunnel_resolve (&sa->tunnel, FIB_NODE_TYPE_IPSEC_SA, sa_index); + + if (rv) { pool_put (im->sad, sa); - return VNET_API_ERROR_NO_SUCH_FIB; + return rv; } - - sa->fib_entry_index = fib_entry_track (sa->tx_fib_index, - &pfx, - FIB_NODE_TYPE_IPSEC_SA, - sa_index, &sa->sibling); ipsec_sa_stack (sa); /* generate header templates */ if (ipsec_sa_is_set_IS_TUNNEL_V6 (sa)) { - sa->ip6_hdr.ip_version_traffic_class_and_flow_label = 0x60; - ip6_set_dscp_network_order (&sa->ip6_hdr, sa->dscp); - - 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 (ipsec_sa_is_set_UDP_ENCAP (sa)) - sa->ip6_hdr.protocol = IP_PROTOCOL_UDP; - else - sa->ip6_hdr.protocol = IP_PROTOCOL_IPSEC_ESP; + tunnel_build_v6_hdr (&sa->tunnel, + (ipsec_sa_is_set_UDP_ENCAP (sa) ? + IP_PROTOCOL_UDP : + IP_PROTOCOL_IPSEC_ESP), + &sa->ip6_hdr); } 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; - sa->ip4_hdr.tos = sa->dscp << 2; - - if (ipsec_sa_is_set_UDP_ENCAP (sa)) - 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); + tunnel_build_v4_hdr (&sa->tunnel, + (ipsec_sa_is_set_UDP_ENCAP (sa) ? + IP_PROTOCOL_UDP : + IP_PROTOCOL_IPSEC_ESP), + &sa->ip4_hdr); } } @@ -370,6 +326,7 @@ ipsec_sa_del (ipsec_sa_t * sa) sa_index = sa - im->sad; hash_unset (im->sa_index_by_sa_id, sa->id); + tunnel_unresolve (&sa->tunnel); /* no recovery possible when deleting an SA */ (void) ipsec_call_add_del_callbacks (im, sa, sa_index, 0); @@ -378,10 +335,7 @@ ipsec_sa_del (ipsec_sa_t * sa) ipsec_unregister_udp_port (clib_net_to_host_u16 (sa->udp_hdr.dst_port)); if (ipsec_sa_is_set_IS_TUNNEL (sa) && !ipsec_sa_is_set_IS_INBOUND (sa)) - { - fib_entry_untrack (sa->fib_entry_index, sa->sibling); - dpo_reset (&sa->dpo); - } + dpo_reset (&sa->dpo); vnet_crypto_key_del (vm, sa->crypto_key_index); if (sa->integ_alg != IPSEC_INTEG_ALG_NONE) vnet_crypto_key_del (vm, sa->integ_key_index); diff --git a/src/vnet/ipsec/ipsec_sa.h b/src/vnet/ipsec/ipsec_sa.h index 7a52e831c77..84abd6ef4b4 100644 --- a/src/vnet/ipsec/ipsec_sa.h +++ b/src/vnet/ipsec/ipsec_sa.h @@ -174,8 +174,7 @@ typedef struct ipsec_protocol_t protocol; tunnel_encap_decap_flags_t tunnel_flags; - ip_dscp_t dscp; - u8 __pad2[1]; + u8 __pad[2]; /* data accessed by dataplane code should be above this comment */ CLIB_CACHE_LINE_ALIGN_MARK (cacheline2); @@ -203,8 +202,7 @@ typedef struct u64 data; } async_op_data; - ip46_address_t tunnel_src_addr; - ip46_address_t tunnel_dst_addr; + tunnel_t tunnel; fib_node_t node; @@ -214,10 +212,6 @@ typedef struct vnet_crypto_alg_t integ_calg; vnet_crypto_alg_t crypto_calg; - fib_node_index_t fib_entry_index; - u32 sibling; - u32 tx_fib_index; - /* else u8 packed */ ipsec_crypto_alg_t crypto_alg; ipsec_integ_alg_t integ_alg; @@ -258,21 +252,12 @@ extern vlib_combined_counter_main_t ipsec_sa_counters; extern void ipsec_mk_key (ipsec_key_t * key, const u8 * data, u8 len); -extern int ipsec_sa_add_and_lock (u32 id, - u32 spi, - ipsec_protocol_t proto, - ipsec_crypto_alg_t crypto_alg, - const ipsec_key_t * ck, - ipsec_integ_alg_t integ_alg, - const ipsec_key_t * ik, - ipsec_sa_flags_t flags, - u32 tx_table_id, - u32 salt, - const ip46_address_t * tunnel_src_addr, - const ip46_address_t * tunnel_dst_addr, - tunnel_encap_decap_flags_t tunnel_flags, - ip_dscp_t dscp, - u32 * sa_index, u16 src_port, u16 dst_port); +extern int +ipsec_sa_add_and_lock (u32 id, u32 spi, ipsec_protocol_t proto, + ipsec_crypto_alg_t crypto_alg, const ipsec_key_t *ck, + ipsec_integ_alg_t integ_alg, const ipsec_key_t *ik, + ipsec_sa_flags_t flags, u32 salt, u16 src_port, + u16 dst_port, const tunnel_t *tun, u32 *sa_out_index); extern index_t ipsec_sa_find_and_lock (u32 id); extern int ipsec_sa_unlock_id (u32 id); extern void ipsec_sa_unlock (index_t sai); diff --git a/src/vnet/ipsec/ipsec_tun.c b/src/vnet/ipsec/ipsec_tun.c index 63e063fcee3..74340256f38 100644 --- a/src/vnet/ipsec/ipsec_tun.c +++ b/src/vnet/ipsec/ipsec_tun.c @@ -470,13 +470,13 @@ ipsec_tun_protect_set_crypto_addr (ipsec_tun_protect_t * itp) ({ if (ipsec_sa_is_set_IS_TUNNEL (sa)) { - itp->itp_crypto.src = sa->tunnel_dst_addr; - itp->itp_crypto.dst = sa->tunnel_src_addr; - if (!(itp->itp_flags & IPSEC_PROTECT_ITF)) - { - ipsec_sa_set_IS_PROTECT (sa); - itp->itp_flags |= IPSEC_PROTECT_ENCAPED; - } + itp->itp_crypto.src = ip_addr_46 (&sa->tunnel.t_dst); + itp->itp_crypto.dst = ip_addr_46 (&sa->tunnel.t_src); + if (!(itp->itp_flags & IPSEC_PROTECT_ITF)) + { + ipsec_sa_set_IS_PROTECT (sa); + itp->itp_flags |= IPSEC_PROTECT_ENCAPED; + } } else { diff --git a/src/vnet/ipsec/ipsec_tun.h b/src/vnet/ipsec/ipsec_tun.h index 7ae00992faa..070831fdca9 100644 --- a/src/vnet/ipsec/ipsec_tun.h +++ b/src/vnet/ipsec/ipsec_tun.h @@ -162,10 +162,6 @@ extern u8 *format_ipsec_tun_protect_index (u8 * s, va_list * args); extern void ipsec_tun_register_nodes (ip_address_family_t af); extern void ipsec_tun_unregister_nodes (ip_address_family_t af); -// FIXME -extern vlib_node_registration_t ipsec4_tun_input_node; -extern vlib_node_registration_t ipsec6_tun_input_node; - /* * DP API */ diff --git a/src/vnet/ipsec/ipsec_types.api b/src/vnet/ipsec/ipsec_types.api index ca1b3788e64..b47355908e7 100644 --- a/src/vnet/ipsec/ipsec_types.api +++ b/src/vnet/ipsec/ipsec_types.api @@ -14,7 +14,7 @@ * limitations under the License. */ -option version = "3.0.0"; +option version = "3.0.1"; import "vnet/ip/ip_types.api"; import "vnet/tunnel/tunnel_types.api"; @@ -162,6 +162,28 @@ typedef ipsec_sad_entry_v2 u16 udp_dst_port [default=4500]; }; +typedef ipsec_sad_entry_v3 +{ + u32 sad_id; + u32 spi; + + vl_api_ipsec_proto_t protocol; + + vl_api_ipsec_crypto_alg_t crypto_algorithm; + vl_api_key_t crypto_key; + + vl_api_ipsec_integ_alg_t integrity_algorithm; + vl_api_key_t integrity_key; + + vl_api_ipsec_sad_flags_t flags; + + vl_api_tunnel_t tunnel; + + u32 salt; + u16 udp_src_port [default=4500]; + u16 udp_dst_port [default=4500]; +}; + /* * Local Variables: diff --git a/src/vnet/tunnel/tunnel.c b/src/vnet/tunnel/tunnel.c index 1bd03eb4a1a..d45a46205d8 100644 --- a/src/vnet/tunnel/tunnel.c +++ b/src/vnet/tunnel/tunnel.c @@ -174,16 +174,14 @@ unformat_tunnel (unformat_input_t *input, va_list *args) unformat (input, "src %U", unformat_ip_address, &t->t_src); unformat (input, "dst %U", unformat_ip_address, &t->t_dst); - unformat (input, "table-id:%d", &t->t_table_id); - unformat (input, "hop-limit:%d", &t->t_hop_limit); + unformat (input, "table-id %d", &t->t_table_id); + unformat (input, "hop-limit %d", &t->t_hop_limit); unformat (input, "%U", unformat_ip_dscp, &t->t_dscp); unformat (input, "%U", unformat_tunnel_encap_decap_flags, &t->t_encap_decap_flags); unformat (input, "%U", unformat_tunnel_flags, &t->t_flags); unformat (input, "%U", unformat_tunnel_mode, &t->t_mode); - ASSERT (!"Check not 4 and 6"); - return (1); } |