X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fvnet%2Fipsec%2Fipsec_api.c;h=eb78dbdd319efbca9c1be268934916d4192d7f1e;hb=17dcec0b9;hp=da78f3d2496f4e52b69fe42a49eae72274f9be85;hpb=6c4dae27e75fc668f86c9cca0f3f58273b680621;p=vpp.git diff --git a/src/vnet/ipsec/ipsec_api.c b/src/vnet/ipsec/ipsec_api.c index da78f3d2496..eb78dbdd319 100644 --- a/src/vnet/ipsec/ipsec_api.c +++ b/src/vnet/ipsec/ipsec_api.c @@ -23,6 +23,8 @@ #include #include #include +#include +#include #include @@ -47,33 +49,37 @@ #include -#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_ADD_DEL_ENTRY, ipsec_spd_add_del_entry) \ -_(IPSEC_SAD_ADD_DEL_ENTRY, ipsec_sad_add_del_entry) \ -_(IPSEC_SA_SET_KEY, ipsec_sa_set_key) \ -_(IPSEC_SA_DUMP, ipsec_sa_dump) \ -_(IPSEC_SPD_DUMP, ipsec_spd_dump) \ -_(IPSEC_TUNNEL_IF_ADD_DEL, ipsec_tunnel_if_add_del) \ -_(IPSEC_TUNNEL_IF_SET_KEY, ipsec_tunnel_if_set_key) \ -_(IPSEC_TUNNEL_IF_SET_SA, ipsec_tunnel_if_set_sa) \ -_(IKEV2_PROFILE_ADD_DEL, ikev2_profile_add_del) \ -_(IKEV2_PROFILE_SET_AUTH, ikev2_profile_set_auth) \ -_(IKEV2_PROFILE_SET_ID, ikev2_profile_set_id) \ -_(IKEV2_PROFILE_SET_TS, ikev2_profile_set_ts) \ -_(IKEV2_SET_LOCAL_KEY, ikev2_set_local_key) \ -_(IKEV2_SET_RESPONDER, ikev2_set_responder) \ -_(IKEV2_SET_IKE_TRANSFORMS, ikev2_set_ike_transforms) \ -_(IKEV2_SET_ESP_TRANSFORMS, ikev2_set_esp_transforms) \ -_(IKEV2_SET_SA_LIFETIME, ikev2_set_sa_lifetime) \ -_(IKEV2_INITIATE_SA_INIT, ikev2_initiate_sa_init) \ -_(IKEV2_INITIATE_DEL_IKE_SA, ikev2_initiate_del_ike_sa) \ -_(IKEV2_INITIATE_DEL_CHILD_SA, ikev2_initiate_del_child_sa) \ -_(IKEV2_INITIATE_REKEY_CHILD_SA, ikev2_initiate_rekey_child_sa) - -static void vl_api_ipsec_spd_add_del_t_handler - (vl_api_ipsec_spd_add_del_t * mp) +#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_SA_SET_KEY, ipsec_sa_set_key) \ +_(IPSEC_SA_DUMP, ipsec_sa_dump) \ +_(IPSEC_SPDS_DUMP, ipsec_spds_dump) \ +_(IPSEC_SPD_DUMP, ipsec_spd_dump) \ +_(IPSEC_SPD_INTERFACE_DUMP, ipsec_spd_interface_dump) \ +_(IPSEC_TUNNEL_IF_ADD_DEL, ipsec_tunnel_if_add_del) \ +_(IPSEC_TUNNEL_IF_SET_KEY, ipsec_tunnel_if_set_key) \ +_(IPSEC_TUNNEL_IF_SET_SA, ipsec_tunnel_if_set_sa) \ +_(IKEV2_PROFILE_ADD_DEL, ikev2_profile_add_del) \ +_(IKEV2_PROFILE_SET_AUTH, ikev2_profile_set_auth) \ +_(IKEV2_PROFILE_SET_ID, ikev2_profile_set_id) \ +_(IKEV2_PROFILE_SET_TS, ikev2_profile_set_ts) \ +_(IKEV2_SET_LOCAL_KEY, ikev2_set_local_key) \ +_(IKEV2_SET_RESPONDER, ikev2_set_responder) \ +_(IKEV2_SET_IKE_TRANSFORMS, ikev2_set_ike_transforms) \ +_(IKEV2_SET_ESP_TRANSFORMS, ikev2_set_esp_transforms) \ +_(IKEV2_SET_SA_LIFETIME, ikev2_set_sa_lifetime) \ +_(IKEV2_INITIATE_SA_INIT, ikev2_initiate_sa_init) \ +_(IKEV2_INITIATE_DEL_IKE_SA, ikev2_initiate_del_ike_sa) \ +_(IKEV2_INITIATE_DEL_CHILD_SA, ikev2_initiate_del_child_sa) \ +_(IKEV2_INITIATE_REKEY_CHILD_SA, ikev2_initiate_rekey_child_sa) \ +_(IPSEC_SELECT_BACKEND, ipsec_select_backend) \ +_(IPSEC_BACKEND_DUMP, ipsec_backend_dump) + +static void +vl_api_ipsec_spd_add_del_t_handler (vl_api_ipsec_spd_add_del_t * mp) { #if WITH_LIBSSL == 0 clib_warning ("unimplemented"); @@ -114,57 +120,72 @@ static void vl_api_ipsec_interface_add_del_spd_t_handler REPLY_MACRO (VL_API_IPSEC_INTERFACE_ADD_DEL_SPD_REPLY); } -static void vl_api_ipsec_spd_add_del_entry_t_handler - (vl_api_ipsec_spd_add_del_entry_t * mp) +static int +ipsec_spd_action_decode (vl_api_ipsec_spd_action_t in, + ipsec_policy_action_t * out) +{ + in = clib_net_to_host_u32 (in); + + switch (in) + { +#define _(v,f,s) case IPSEC_API_SPD_ACTION_##f: \ + *out = IPSEC_POLICY_ACTION_##f; \ + return (0); + foreach_ipsec_policy_action +#undef _ + } + return (VNET_API_ERROR_UNIMPLEMENTED); +} + +static void vl_api_ipsec_spd_entry_add_del_t_handler + (vl_api_ipsec_spd_entry_add_del_t * mp) { vlib_main_t *vm __attribute__ ((unused)) = vlib_get_main (); - vl_api_ipsec_spd_add_del_entry_reply_t *rmp; + vl_api_ipsec_spd_entry_add_del_reply_t *rmp; + ip46_type_t itype; int rv; #if WITH_LIBSSL > 0 ipsec_policy_t p; - memset (&p, 0, sizeof (p)); + clib_memset (&p, 0, sizeof (p)); - p.id = ntohl (mp->spd_id); - p.priority = ntohl (mp->priority); - p.is_outbound = mp->is_outbound; - p.is_ipv6 = mp->is_ipv6; + p.id = ntohl (mp->entry.spd_id); + p.priority = ntohl (mp->entry.priority); + p.is_outbound = mp->entry.is_outbound; + + itype = ip_address_decode (&mp->entry.remote_address_start, &p.raddr.start); + ip_address_decode (&mp->entry.remote_address_stop, &p.raddr.stop); + ip_address_decode (&mp->entry.local_address_start, &p.laddr.start); + ip_address_decode (&mp->entry.local_address_stop, &p.laddr.stop); + + p.is_ipv6 = (itype == IP46_TYPE_IP6); + + p.protocol = mp->entry.protocol; + p.rport.start = ntohs (mp->entry.remote_port_start); + p.rport.stop = ntohs (mp->entry.remote_port_stop); + p.lport.start = ntohs (mp->entry.local_port_start); + p.lport.stop = ntohs (mp->entry.local_port_stop); + + rv = ipsec_spd_action_decode (mp->entry.policy, &p.policy); + + if (rv) + goto out; - if (mp->is_ipv6 || mp->is_ip_any) - { - clib_memcpy (&p.raddr.start, mp->remote_address_start, 16); - clib_memcpy (&p.raddr.stop, mp->remote_address_stop, 16); - clib_memcpy (&p.laddr.start, mp->local_address_start, 16); - clib_memcpy (&p.laddr.stop, mp->local_address_stop, 16); - } - else - { - clib_memcpy (&p.raddr.start.ip4.data, mp->remote_address_start, 4); - clib_memcpy (&p.raddr.stop.ip4.data, mp->remote_address_stop, 4); - clib_memcpy (&p.laddr.start.ip4.data, mp->local_address_start, 4); - clib_memcpy (&p.laddr.stop.ip4.data, mp->local_address_stop, 4); - } - p.protocol = mp->protocol; - p.rport.start = ntohs (mp->remote_port_start); - p.rport.stop = ntohs (mp->remote_port_stop); - p.lport.start = ntohs (mp->local_port_start); - p.lport.stop = ntohs (mp->local_port_stop); /* policy action resolve unsupported */ - if (mp->policy == IPSEC_POLICY_ACTION_RESOLVE) + if (p.policy == IPSEC_POLICY_ACTION_RESOLVE) { clib_warning ("unsupported action: 'resolve'"); rv = VNET_API_ERROR_UNIMPLEMENTED; goto out; } - p.policy = mp->policy; - p.sa_id = ntohl (mp->sa_id); + p.sa_id = ntohl (mp->entry.sa_id); rv = ipsec_add_del_policy (vm, &p, mp->is_add); if (rv) goto out; - if (mp->is_ip_any) + if (mp->entry.is_ip_any) { p.is_ipv6 = 1; rv = ipsec_add_del_policy (vm, &p, mp->is_add); @@ -175,65 +196,128 @@ static void vl_api_ipsec_spd_add_del_entry_t_handler #endif out: - REPLY_MACRO (VL_API_IPSEC_SPD_ADD_DEL_ENTRY_REPLY); + REPLY_MACRO (VL_API_IPSEC_SPD_ENTRY_ADD_DEL_REPLY); } -static void vl_api_ipsec_sad_add_del_entry_t_handler - (vl_api_ipsec_sad_add_del_entry_t * mp) +static int +ipsec_proto_decode (vl_api_ipsec_proto_t in, ipsec_protocol_t * out) { - vlib_main_t *vm __attribute__ ((unused)) = vlib_get_main (); - vl_api_ipsec_sad_add_del_entry_reply_t *rmp; - int rv; -#if WITH_LIBSSL > 0 - ipsec_main_t *im = &ipsec_main; - ipsec_sa_t sa; - - memset (&sa, 0, sizeof (sa)); + in = clib_net_to_host_u32 (in); - sa.id = ntohl (mp->sad_id); - sa.spi = ntohl (mp->spi); - sa.protocol = mp->protocol; - /* check for unsupported crypto-alg */ - if (mp->crypto_algorithm < IPSEC_CRYPTO_ALG_AES_CBC_128 || - mp->crypto_algorithm >= IPSEC_CRYPTO_N_ALG) + switch (in) { - clib_warning ("unsupported crypto-alg: '%U'", format_ipsec_crypto_alg, - mp->crypto_algorithm); - rv = VNET_API_ERROR_UNIMPLEMENTED; - goto out; + case IPSEC_API_PROTO_ESP: + *out = IPSEC_PROTOCOL_ESP; + return (0); + case IPSEC_API_PROTO_AH: + *out = IPSEC_PROTOCOL_AH; + return (0); } - sa.crypto_alg = mp->crypto_algorithm; - sa.crypto_key_len = mp->crypto_key_length; - clib_memcpy (&sa.crypto_key, mp->crypto_key, sizeof (sa.crypto_key)); - /* check for unsupported integ-alg */ - if (mp->integrity_algorithm >= IPSEC_INTEG_N_ALG) + return (VNET_API_ERROR_UNIMPLEMENTED); +} + +static int +ipsec_crypto_algo_decode (vl_api_ipsec_crypto_alg_t in, + ipsec_crypto_alg_t * out) +{ + in = clib_net_to_host_u32 (in); + + switch (in) { - clib_warning ("unsupported integ-alg: '%U'", format_ipsec_integ_alg, - mp->integrity_algorithm); - rv = VNET_API_ERROR_UNIMPLEMENTED; - goto out; +#define _(v,f,s) case IPSEC_API_CRYPTO_ALG_##f: \ + *out = IPSEC_CRYPTO_ALG_##f; \ + return (0); + foreach_ipsec_crypto_alg +#undef _ } + return (VNET_API_ERROR_UNIMPLEMENTED); +} + +static int +ipsec_integ_algo_decode (vl_api_ipsec_integ_alg_t in, ipsec_integ_alg_t * out) +{ + in = clib_net_to_host_u32 (in); - sa.integ_alg = mp->integrity_algorithm; - sa.integ_key_len = mp->integrity_key_length; - clib_memcpy (&sa.integ_key, mp->integrity_key, sizeof (sa.integ_key)); - sa.use_esn = mp->use_extended_sequence_number; - sa.is_tunnel = mp->is_tunnel; - sa.is_tunnel_ip6 = mp->is_tunnel_ipv6; - if (sa.is_tunnel_ip6) + switch (in) { - clib_memcpy (&sa.tunnel_src_addr, mp->tunnel_src_address, 16); - clib_memcpy (&sa.tunnel_dst_addr, mp->tunnel_dst_address, 16); +#define _(v,f,s) case IPSEC_API_INTEG_ALG_##f: \ + *out = IPSEC_INTEG_ALG_##f; \ + return (0); + foreach_ipsec_integ_alg +#undef _ } - else + return (VNET_API_ERROR_UNIMPLEMENTED); +} + +static void +vl_api_ipsec_key_decode (const vl_api_key_t * key, u8 * len, u8 out[128]) +{ + *len = key->length; + clib_memcpy (out, key->data, key->length); +} + +static void +vl_api_ipsec_sad_flags_decode (vl_api_ipsec_sad_flags_t in, ipsec_sa_t * sa) +{ + in = clib_net_to_host_u32 (in); + + if (in & IPSEC_API_SAD_FLAG_USE_EXTENDED_SEQ_NUM) + sa->use_esn = 1; + if (in & IPSEC_API_SAD_FLAG_USE_ANTI_REPLAY) + sa->use_anti_replay = 1; + if (in & IPSEC_API_SAD_FLAG_IS_TUNNEL) + sa->is_tunnel = 1; + if (in & IPSEC_API_SAD_FLAG_IS_TUNNEL_V6) + sa->is_tunnel_ip6 = 1; + if (in & IPSEC_API_SAD_FLAG_UDP_ENCAP) + sa->udp_encap = 1; +} + + +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; + int rv; +#if WITH_LIBSSL > 0 + ipsec_main_t *im = &ipsec_main; + ipsec_sa_t sa; + + clib_memset (&sa, 0, sizeof (sa)); + + sa.id = ntohl (mp->entry.sad_id); + sa.spi = ntohl (mp->entry.spi); + + rv = ipsec_proto_decode (mp->entry.protocol, &sa.protocol); + + if (rv) + goto out; + + rv = ipsec_crypto_algo_decode (mp->entry.crypto_algorithm, &sa.crypto_alg); + + if (rv) + goto out; + + rv = ipsec_integ_algo_decode (mp->entry.integrity_algorithm, &sa.integ_alg); + + if (rv) + goto out; + + vl_api_ipsec_key_decode (&mp->entry.crypto_key, + &sa.crypto_key_len, sa.crypto_key); + vl_api_ipsec_key_decode (&mp->entry.integrity_key, + &sa.integ_key_len, sa.integ_key); + + vl_api_ipsec_sad_flags_decode (mp->entry.flags, &sa); + + if (sa.is_tunnel_ip6 || sa.is_tunnel) { - clib_memcpy (&sa.tunnel_src_addr.ip4.data, mp->tunnel_src_address, 4); - clib_memcpy (&sa.tunnel_dst_addr.ip4.data, mp->tunnel_dst_address, 4); + ip_address_decode (&mp->entry.tunnel_src, &sa.tunnel_src_addr); + ip_address_decode (&mp->entry.tunnel_dst, &sa.tunnel_dst_addr); } - sa.use_anti_replay = mp->use_anti_replay; - ASSERT (im->cb.check_support_cb); - clib_error_t *err = im->cb.check_support_cb (&sa); + clib_error_t *err = ipsec_check_support_cb (im, &sa); if (err) { clib_warning ("%s", err->what); @@ -248,7 +332,61 @@ static void vl_api_ipsec_sad_add_del_entry_t_handler #endif out: - REPLY_MACRO (VL_API_IPSEC_SAD_ADD_DEL_ENTRY_REPLY); + REPLY_MACRO (VL_API_IPSEC_SAD_ENTRY_ADD_DEL_REPLY); +} + +static void +send_ipsec_spds_details (ipsec_spd_t * spd, vl_api_registration_t * reg, + u32 context) +{ + vl_api_ipsec_spds_details_t *mp; + + mp = vl_msg_api_alloc (sizeof (*mp)); + clib_memset (mp, 0, sizeof (*mp)); + mp->_vl_msg_id = ntohs (VL_API_IPSEC_SPDS_DETAILS); + mp->context = context; + + mp->spd_id = htonl (spd->id); + mp->npolicies = htonl (pool_len (spd->policies)); + + vl_api_send_msg (reg, (u8 *) mp); +} + +static void +vl_api_ipsec_spds_dump_t_handler (vl_api_ipsec_spds_dump_t * mp) +{ + vl_api_registration_t *reg; + ipsec_main_t *im = &ipsec_main; + ipsec_spd_t *spd; +#if WITH_LIBSSL > 0 + reg = vl_api_client_index_to_registration (mp->client_index); + if (!reg) + return; + + /* *INDENT-OFF* */ + pool_foreach (spd, im->spds, ({ + send_ipsec_spds_details (spd, reg, mp->context); + })); + /* *INDENT-ON* */ +#else + clib_warning ("unimplemented"); +#endif +} + +vl_api_ipsec_spd_action_t +ipsec_spd_action_encode (ipsec_policy_action_t in) +{ + vl_api_ipsec_spd_action_t out = IPSEC_API_SPD_ACTION_BYPASS; + + switch (in) + { +#define _(v,f,s) case IPSEC_POLICY_ACTION_##f: \ + out = IPSEC_API_SPD_ACTION_##f; \ + break; + foreach_ipsec_policy_action +#undef _ + } + return (clib_host_to_net_u32 (out)); } static void @@ -258,35 +396,30 @@ send_ipsec_spd_details (ipsec_policy_t * p, vl_api_registration_t * reg, vl_api_ipsec_spd_details_t *mp; mp = vl_msg_api_alloc (sizeof (*mp)); - memset (mp, 0, sizeof (*mp)); + clib_memset (mp, 0, sizeof (*mp)); mp->_vl_msg_id = ntohs (VL_API_IPSEC_SPD_DETAILS); mp->context = context; - mp->spd_id = htonl (p->id); - mp->priority = htonl (p->priority); - mp->is_outbound = p->is_outbound; - mp->is_ipv6 = p->is_ipv6; - if (p->is_ipv6) - { - memcpy (mp->local_start_addr, &p->laddr.start.ip6, 16); - memcpy (mp->local_stop_addr, &p->laddr.stop.ip6, 16); - memcpy (mp->remote_start_addr, &p->raddr.start.ip6, 16); - memcpy (mp->remote_stop_addr, &p->raddr.stop.ip6, 16); - } - else - { - memcpy (mp->local_start_addr, &p->laddr.start.ip4, 4); - memcpy (mp->local_stop_addr, &p->laddr.stop.ip4, 4); - memcpy (mp->remote_start_addr, &p->raddr.start.ip4, 4); - memcpy (mp->remote_stop_addr, &p->raddr.stop.ip4, 4); - } - mp->local_start_port = htons (p->lport.start); - mp->local_stop_port = htons (p->lport.stop); - mp->remote_start_port = htons (p->rport.start); - mp->remote_stop_port = htons (p->rport.stop); - mp->protocol = p->protocol; - mp->policy = p->policy; - mp->sa_id = htonl (p->sa_id); + mp->entry.spd_id = htonl (p->id); + mp->entry.priority = htonl (p->priority); + mp->entry.is_outbound = p->is_outbound; + + ip_address_encode (&p->laddr.start, IP46_TYPE_ANY, + &mp->entry.local_address_start); + ip_address_encode (&p->laddr.stop, IP46_TYPE_ANY, + &mp->entry.local_address_stop); + ip_address_encode (&p->raddr.start, IP46_TYPE_ANY, + &mp->entry.remote_address_start); + ip_address_encode (&p->raddr.stop, IP46_TYPE_ANY, + &mp->entry.remote_address_stop); + mp->entry.local_port_start = htons (p->lport.start); + mp->entry.local_port_stop = htons (p->lport.stop); + mp->entry.remote_port_start = htons (p->rport.start); + mp->entry.remote_port_stop = htons (p->rport.stop); + mp->entry.protocol = p->protocol; + mp->entry.policy = ipsec_spd_action_encode (p->policy); + mp->entry.sa_id = htonl (p->sa_id); + mp->bytes = clib_host_to_net_u64 (p->counter.bytes); mp->packets = clib_host_to_net_u64 (p->counter.packets); @@ -327,6 +460,60 @@ vl_api_ipsec_spd_dump_t_handler (vl_api_ipsec_spd_dump_t * mp) #endif } +static void +send_ipsec_spd_interface_details (vl_api_registration_t * reg, u32 spd_index, + u32 sw_if_index, u32 context) +{ + vl_api_ipsec_spd_interface_details_t *mp; + + mp = vl_msg_api_alloc (sizeof (*mp)); + clib_memset (mp, 0, sizeof (*mp)); + mp->_vl_msg_id = ntohs (VL_API_IPSEC_SPD_INTERFACE_DETAILS); + mp->context = context; + + mp->spd_index = htonl (spd_index); + mp->sw_if_index = htonl (sw_if_index); + + vl_api_send_msg (reg, (u8 *) mp); +} + +static void +vl_api_ipsec_spd_interface_dump_t_handler (vl_api_ipsec_spd_interface_dump_t * + mp) +{ + ipsec_main_t *im = &ipsec_main; + vl_api_registration_t *reg; + u32 k, v, spd_index; + +#if WITH_LIBSSL > 0 + reg = vl_api_client_index_to_registration (mp->client_index); + if (!reg) + return; + + if (mp->spd_index_valid) + { + spd_index = ntohl (mp->spd_index); + /* *INDENT-OFF* */ + hash_foreach(k, v, im->spd_index_by_sw_if_index, ({ + if (v == spd_index) + send_ipsec_spd_interface_details(reg, v, k, mp->context); + })); + /* *INDENT-ON* */ + } + else + { + /* *INDENT-OFF* */ + hash_foreach(k, v, im->spd_index_by_sw_if_index, ({ + send_ipsec_spd_interface_details(reg, v, k, mp->context); + })); + /* *INDENT-ON* */ + } + +#else + clib_warning ("unimplemented"); +#endif +} + static void vl_api_ipsec_sa_set_key_t_handler (vl_api_ipsec_sa_set_key_t * mp) { @@ -336,10 +523,11 @@ vl_api_ipsec_sa_set_key_t_handler (vl_api_ipsec_sa_set_key_t * mp) #if WITH_LIBSSL > 0 ipsec_sa_t sa; sa.id = ntohl (mp->sa_id); - sa.crypto_key_len = mp->crypto_key_length; - clib_memcpy (&sa.crypto_key, mp->crypto_key, sizeof (sa.crypto_key)); - sa.integ_key_len = mp->integrity_key_length; - clib_memcpy (&sa.integ_key, mp->integrity_key, sizeof (sa.integ_key)); + + vl_api_ipsec_key_decode (&mp->crypto_key, + &sa.crypto_key_len, sa.crypto_key); + vl_api_ipsec_key_decode (&mp->integrity_key, + &sa.integ_key_len, sa.integ_key); rv = ipsec_set_sa_key (vm, &sa); #else @@ -362,7 +550,7 @@ vl_api_ipsec_tunnel_if_add_del_t_handler (vl_api_ipsec_tunnel_if_add_del_t * #if WITH_LIBSSL > 0 ipsec_add_del_tunnel_args_t tun; - memset (&tun, 0, sizeof (ipsec_add_del_tunnel_args_t)); + clib_memset (&tun, 0, sizeof (ipsec_add_del_tunnel_args_t)); tun.is_add = mp->is_add; tun.esn = mp->esn; @@ -375,6 +563,8 @@ vl_api_ipsec_tunnel_if_add_del_t_handler (vl_api_ipsec_tunnel_if_add_del_t * tun.integ_alg = mp->integ_alg; tun.local_integ_key_len = mp->local_integ_key_len; tun.remote_integ_key_len = mp->remote_integ_key_len; + tun.udp_encap = mp->udp_encap; + tun.tx_table_id = ntohl (mp->tx_table_id); memcpy (&tun.local_ip, mp->local_ip, 4); memcpy (&tun.remote_ip, mp->remote_ip, 4); memcpy (&tun.local_crypto_key, &mp->local_crypto_key, @@ -385,6 +575,8 @@ vl_api_ipsec_tunnel_if_add_del_t_handler (vl_api_ipsec_tunnel_if_add_del_t * mp->local_integ_key_len); memcpy (&tun.remote_integ_key, &mp->remote_integ_key, mp->remote_integ_key_len); + tun.renumber = mp->renumber; + tun.show_instance = ntohl (mp->show_instance); rv = ipsec_add_del_tunnel_if_internal (vnm, &tun, &sw_if_index); @@ -406,7 +598,7 @@ send_ipsec_sa_details (ipsec_sa_t * sa, vl_api_registration_t * reg, vl_api_ipsec_sa_details_t *mp; mp = vl_msg_api_alloc (sizeof (*mp)); - memset (mp, 0, sizeof (*mp)); + clib_memset (mp, 0, sizeof (*mp)); mp->_vl_msg_id = ntohs (VL_API_IPSEC_SA_DETAILS); mp->context = context; @@ -455,6 +647,10 @@ send_ipsec_sa_details (ipsec_sa_t * sa, vl_api_registration_t * reg, if (sa->use_anti_replay) mp->replay_window = clib_host_to_net_u64 (sa->replay_window); mp->total_data_size = clib_host_to_net_u64 (sa->total_data_size); + mp->udp_encap = sa->udp_encap; + + mp->tx_table_id = + htonl (fib_table_get_table_id (sa->tx_fib_index, FIB_PROTOCOL_IP4)); vl_api_send_msg (reg, (u8 *) mp); } @@ -524,7 +720,7 @@ vl_api_ipsec_tunnel_if_set_key_t_handler (vl_api_ipsec_tunnel_if_set_key_t * case IPSEC_IF_SET_KEY_TYPE_LOCAL_CRYPTO: case IPSEC_IF_SET_KEY_TYPE_REMOTE_CRYPTO: if (mp->alg < IPSEC_CRYPTO_ALG_AES_CBC_128 || - mp->alg > IPSEC_CRYPTO_N_ALG) + mp->alg >= IPSEC_CRYPTO_N_ALG) { rv = VNET_API_ERROR_UNIMPLEMENTED; goto out; @@ -532,7 +728,7 @@ vl_api_ipsec_tunnel_if_set_key_t_handler (vl_api_ipsec_tunnel_if_set_key_t * break; case IPSEC_IF_SET_KEY_TYPE_LOCAL_INTEG: case IPSEC_IF_SET_KEY_TYPE_REMOTE_INTEG: - if (mp->alg > IPSEC_INTEG_N_ALG) + if (mp->alg >= IPSEC_INTEG_N_ALG) { rv = VNET_API_ERROR_UNIMPLEMENTED; goto out; @@ -613,9 +809,10 @@ static void #if WITH_LIBSSL > 0 vlib_main_t *vm = vlib_get_main (); clib_error_t *error; + int data_len = ntohl (mp->data_len); u8 *tmp = format (0, "%s", mp->name); - u8 *data = vec_new (u8, mp->data_len); - clib_memcpy (data, mp->data, mp->data_len); + u8 *data = vec_new (u8, data_len); + clib_memcpy (data, mp->data, data_len); error = ikev2_set_profile_auth (vm, tmp, mp->auth_method, data, mp->is_hex); vec_free (tmp); vec_free (data); @@ -638,8 +835,9 @@ vl_api_ikev2_profile_set_id_t_handler (vl_api_ikev2_profile_set_id_t * mp) vlib_main_t *vm = vlib_get_main (); clib_error_t *error; u8 *tmp = format (0, "%s", mp->name); - u8 *data = vec_new (u8, mp->data_len); - clib_memcpy (data, mp->data, mp->data_len); + int data_len = ntohl (mp->data_len); + u8 *data = vec_new (u8, data_len); + clib_memcpy (data, mp->data, data_len); error = ikev2_set_profile_id (vm, tmp, mp->id_type, data, mp->is_local); vec_free (tmp); vec_free (data); @@ -886,7 +1084,7 @@ static void /* * ipsec_api_hookup * Add vpe's API message handlers to the table. - * vlib has alread mapped shared memory and + * vlib has already mapped shared memory and * added the client registration handlers. * See .../vlib-api/vlibmemory/memclnt_vlib.c:memclnt_process() */ @@ -902,6 +1100,99 @@ setup_message_id_table (api_main_t * am) #undef _ } +static void +vl_api_ipsec_backend_dump_t_handler (vl_api_ipsec_backend_dump_t * mp) +{ + vl_api_registration_t *rp; + ipsec_main_t *im = &ipsec_main; + u32 context = mp->context; + + rp = vl_api_client_index_to_registration (mp->client_index); + + if (rp == 0) + { + clib_warning ("Client %d AWOL", mp->client_index); + return; + } + + ipsec_ah_backend_t *ab; + ipsec_esp_backend_t *eb; + /* *INDENT-OFF* */ + pool_foreach (ab, im->ah_backends, { + vl_api_ipsec_backend_details_t *mp = vl_msg_api_alloc (sizeof (*mp)); + clib_memset (mp, 0, sizeof (*mp)); + mp->_vl_msg_id = ntohs (VL_API_IPSEC_BACKEND_DETAILS); + mp->context = context; + snprintf ((char *)mp->name, sizeof (mp->name), "%.*s", vec_len (ab->name), + ab->name); + mp->protocol = ntohl (IPSEC_API_PROTO_AH); + mp->index = ab - im->ah_backends; + mp->active = mp->index == im->ah_current_backend ? 1 : 0; + vl_api_send_msg (rp, (u8 *)mp); + }); + pool_foreach (eb, im->esp_backends, { + vl_api_ipsec_backend_details_t *mp = vl_msg_api_alloc (sizeof (*mp)); + clib_memset (mp, 0, sizeof (*mp)); + mp->_vl_msg_id = ntohs (VL_API_IPSEC_BACKEND_DETAILS); + mp->context = context; + snprintf ((char *)mp->name, sizeof (mp->name), "%.*s", vec_len (eb->name), + eb->name); + mp->protocol = ntohl (IPSEC_API_PROTO_ESP); + mp->index = eb - im->esp_backends; + mp->active = mp->index == im->esp_current_backend ? 1 : 0; + vl_api_send_msg (rp, (u8 *)mp); + }); + /* *INDENT-ON* */ +} + +static void +vl_api_ipsec_select_backend_t_handler (vl_api_ipsec_select_backend_t * mp) +{ + ipsec_main_t *im = &ipsec_main; + vl_api_ipsec_select_backend_reply_t *rmp; + ipsec_protocol_t protocol; + int rv = 0; + if (pool_elts (im->sad) > 0) + { + rv = VNET_API_ERROR_INSTANCE_IN_USE; + goto done; + } + + rv = ipsec_proto_decode (mp->protocol, &protocol); + + if (rv) + goto done; + +#if WITH_LIBSSL > 0 + switch (protocol) + { + case IPSEC_PROTOCOL_ESP: + if (pool_is_free_index (im->esp_backends, mp->index)) + { + rv = VNET_API_ERROR_INVALID_VALUE; + break; + } + ipsec_select_esp_backend (im, mp->index); + break; + case IPSEC_PROTOCOL_AH: + if (pool_is_free_index (im->ah_backends, mp->index)) + { + rv = VNET_API_ERROR_INVALID_VALUE; + break; + } + ipsec_select_ah_backend (im, mp->index); + break; + default: + rv = VNET_API_ERROR_INVALID_VALUE; + break; + } +#else + clib_warning ("unimplemented"); /* FIXME */ +#endif +done: + REPLY_MACRO (VL_API_IPSEC_SELECT_BACKEND_REPLY); +} + static clib_error_t * ipsec_api_hookup (vlib_main_t * vm) {