+ W (ret);
+ return ret;
+}
+
+static int
+api_ipsec_sa_set_key (vat_main_t * vam)
+{
+ unformat_input_t *i = vam->input;
+ vl_api_ipsec_sa_set_key_t *mp;
+ u32 sa_id;
+ u8 *ck = 0, *ik = 0;
+ int ret;
+
+ while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
+ {
+ if (unformat (i, "sa_id %d", &sa_id))
+ ;
+ else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
+ ;
+ else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
+ ;
+ else
+ {
+ clib_warning ("parse error '%U'", format_unformat_error, i);
+ return -99;
+ }
+ }
+
+ M (IPSEC_SA_SET_KEY, mp);
+
+ mp->sa_id = ntohl (sa_id);
+ mp->crypto_key_length = vec_len (ck);
+ mp->integrity_key_length = vec_len (ik);
+
+ if (mp->crypto_key_length > sizeof (mp->crypto_key))
+ mp->crypto_key_length = sizeof (mp->crypto_key);
+
+ if (mp->integrity_key_length > sizeof (mp->integrity_key))
+ mp->integrity_key_length = sizeof (mp->integrity_key);
+
+ if (ck)
+ clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
+ if (ik)
+ clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
+
+ S (mp);
+ W (ret);
+ return ret;
+}
+
+static int
+api_ipsec_tunnel_if_add_del (vat_main_t * vam)
+{
+ unformat_input_t *i = vam->input;
+ vl_api_ipsec_tunnel_if_add_del_t *mp;
+ u32 local_spi = 0, remote_spi = 0;
+ u32 crypto_alg = 0, integ_alg = 0;
+ u8 *lck = NULL, *rck = NULL;
+ u8 *lik = NULL, *rik = NULL;
+ ip4_address_t local_ip = { {0} };
+ ip4_address_t remote_ip = { {0} };
+ u8 is_add = 1;
+ u8 esn = 0;
+ u8 anti_replay = 0;
+ int ret;
+
+ while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
+ {
+ if (unformat (i, "del"))
+ is_add = 0;
+ else if (unformat (i, "esn"))
+ esn = 1;
+ else if (unformat (i, "anti_replay"))
+ anti_replay = 1;
+ else if (unformat (i, "local_spi %d", &local_spi))
+ ;
+ else if (unformat (i, "remote_spi %d", &remote_spi))
+ ;
+ else if (unformat (i, "local_ip %U", unformat_ip4_address, &local_ip))
+ ;
+ else if (unformat (i, "remote_ip %U", unformat_ip4_address, &remote_ip))
+ ;
+ else if (unformat (i, "local_crypto_key %U", unformat_hex_string, &lck))
+ ;
+ else
+ if (unformat (i, "remote_crypto_key %U", unformat_hex_string, &rck))
+ ;
+ else if (unformat (i, "local_integ_key %U", unformat_hex_string, &lik))
+ ;
+ else if (unformat (i, "remote_integ_key %U", unformat_hex_string, &rik))
+ ;
+ else
+ if (unformat
+ (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
+ {
+ if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
+ crypto_alg >= IPSEC_CRYPTO_N_ALG)
+ {
+ errmsg ("unsupported crypto-alg: '%U'\n",
+ format_ipsec_crypto_alg, crypto_alg);
+ return -99;
+ }
+ }
+ else
+ if (unformat
+ (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
+ {
+ if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
+ integ_alg >= IPSEC_INTEG_N_ALG)
+ {
+ errmsg ("unsupported integ-alg: '%U'\n",
+ format_ipsec_integ_alg, integ_alg);
+ return -99;
+ }
+ }
+ else
+ {
+ errmsg ("parse error '%U'\n", format_unformat_error, i);
+ return -99;
+ }
+ }
+
+ M (IPSEC_TUNNEL_IF_ADD_DEL, mp);
+
+ mp->is_add = is_add;
+ mp->esn = esn;
+ mp->anti_replay = anti_replay;
+
+ clib_memcpy (mp->local_ip, &local_ip, sizeof (ip4_address_t));
+ clib_memcpy (mp->remote_ip, &remote_ip, sizeof (ip4_address_t));
+
+ mp->local_spi = htonl (local_spi);
+ mp->remote_spi = htonl (remote_spi);
+ mp->crypto_alg = (u8) crypto_alg;
+
+ mp->local_crypto_key_len = 0;
+ if (lck)
+ {
+ mp->local_crypto_key_len = vec_len (lck);
+ if (mp->local_crypto_key_len > sizeof (mp->local_crypto_key))
+ mp->local_crypto_key_len = sizeof (mp->local_crypto_key);
+ clib_memcpy (mp->local_crypto_key, lck, mp->local_crypto_key_len);
+ }
+
+ mp->remote_crypto_key_len = 0;
+ if (rck)
+ {
+ mp->remote_crypto_key_len = vec_len (rck);
+ if (mp->remote_crypto_key_len > sizeof (mp->remote_crypto_key))
+ mp->remote_crypto_key_len = sizeof (mp->remote_crypto_key);
+ clib_memcpy (mp->remote_crypto_key, rck, mp->remote_crypto_key_len);
+ }
+
+ mp->integ_alg = (u8) integ_alg;
+
+ mp->local_integ_key_len = 0;
+ if (lik)
+ {
+ mp->local_integ_key_len = vec_len (lik);
+ if (mp->local_integ_key_len > sizeof (mp->local_integ_key))
+ mp->local_integ_key_len = sizeof (mp->local_integ_key);
+ clib_memcpy (mp->local_integ_key, lik, mp->local_integ_key_len);
+ }
+
+ mp->remote_integ_key_len = 0;
+ if (rik)
+ {
+ mp->remote_integ_key_len = vec_len (rik);
+ if (mp->remote_integ_key_len > sizeof (mp->remote_integ_key))
+ mp->remote_integ_key_len = sizeof (mp->remote_integ_key);
+ clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
+ }
+
+ S (mp);
+ W (ret);
+ return ret;
+}
+
+static int
+api_ikev2_profile_add_del (vat_main_t * vam)
+{
+ unformat_input_t *i = vam->input;
+ vl_api_ikev2_profile_add_del_t *mp;
+ u8 is_add = 1;
+ u8 *name = 0;
+ int ret;
+
+ const char *valid_chars = "a-zA-Z0-9_";
+
+ while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
+ {
+ if (unformat (i, "del"))
+ is_add = 0;
+ else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
+ vec_add1 (name, 0);
+ else
+ {
+ errmsg ("parse error '%U'", format_unformat_error, i);
+ return -99;
+ }
+ }
+
+ if (!vec_len (name))
+ {
+ errmsg ("profile name must be specified");
+ return -99;
+ }
+
+ if (vec_len (name) > 64)
+ {
+ errmsg ("profile name too long");
+ return -99;
+ }
+
+ M (IKEV2_PROFILE_ADD_DEL, mp);
+
+ clib_memcpy (mp->name, name, vec_len (name));
+ mp->is_add = is_add;
+ vec_free (name);
+
+ S (mp);
+ W (ret);
+ return ret;
+}
+
+static int
+api_ikev2_profile_set_auth (vat_main_t * vam)
+{
+ unformat_input_t *i = vam->input;
+ vl_api_ikev2_profile_set_auth_t *mp;
+ u8 *name = 0;
+ u8 *data = 0;
+ u32 auth_method = 0;
+ u8 is_hex = 0;
+ int ret;
+
+ const char *valid_chars = "a-zA-Z0-9_";
+
+ while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
+ {
+ if (unformat (i, "name %U", unformat_token, valid_chars, &name))
+ vec_add1 (name, 0);
+ else if (unformat (i, "auth_method %U",
+ unformat_ikev2_auth_method, &auth_method))
+ ;
+ else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
+ is_hex = 1;
+ else if (unformat (i, "auth_data %v", &data))
+ ;
+ else
+ {
+ errmsg ("parse error '%U'", format_unformat_error, i);
+ return -99;
+ }
+ }
+
+ if (!vec_len (name))
+ {
+ errmsg ("profile name must be specified");
+ return -99;
+ }
+
+ if (vec_len (name) > 64)
+ {
+ errmsg ("profile name too long");
+ return -99;
+ }
+
+ if (!vec_len (data))
+ {
+ errmsg ("auth_data must be specified");
+ return -99;
+ }
+
+ if (!auth_method)
+ {
+ errmsg ("auth_method must be specified");
+ return -99;
+ }
+
+ M (IKEV2_PROFILE_SET_AUTH, mp);
+
+ mp->is_hex = is_hex;
+ mp->auth_method = (u8) auth_method;
+ mp->data_len = vec_len (data);
+ clib_memcpy (mp->name, name, vec_len (name));
+ clib_memcpy (mp->data, data, vec_len (data));
+ vec_free (name);
+ vec_free (data);
+
+ S (mp);
+ W (ret);
+ return ret;
+}
+
+static int
+api_ikev2_profile_set_id (vat_main_t * vam)
+{
+ unformat_input_t *i = vam->input;
+ vl_api_ikev2_profile_set_id_t *mp;
+ u8 *name = 0;
+ u8 *data = 0;
+ u8 is_local = 0;
+ u32 id_type = 0;
+ ip4_address_t ip4;
+ int ret;
+
+ const char *valid_chars = "a-zA-Z0-9_";
+
+ while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
+ {
+ if (unformat (i, "name %U", unformat_token, valid_chars, &name))
+ vec_add1 (name, 0);
+ else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
+ ;
+ else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
+ {
+ data = vec_new (u8, 4);
+ clib_memcpy (data, ip4.as_u8, 4);
+ }
+ else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
+ ;
+ else if (unformat (i, "id_data %v", &data))
+ ;
+ else if (unformat (i, "local"))
+ is_local = 1;
+ else if (unformat (i, "remote"))
+ is_local = 0;
+ else
+ {
+ errmsg ("parse error '%U'", format_unformat_error, i);
+ return -99;
+ }
+ }
+
+ if (!vec_len (name))
+ {
+ errmsg ("profile name must be specified");
+ return -99;
+ }
+
+ if (vec_len (name) > 64)
+ {
+ errmsg ("profile name too long");
+ return -99;
+ }
+
+ if (!vec_len (data))
+ {
+ errmsg ("id_data must be specified");
+ return -99;
+ }
+
+ if (!id_type)
+ {
+ errmsg ("id_type must be specified");
+ return -99;
+ }
+
+ M (IKEV2_PROFILE_SET_ID, mp);
+
+ mp->is_local = is_local;
+ mp->id_type = (u8) id_type;
+ mp->data_len = vec_len (data);
+ clib_memcpy (mp->name, name, vec_len (name));
+ clib_memcpy (mp->data, data, vec_len (data));
+ vec_free (name);
+ vec_free (data);
+
+ S (mp);
+ W (ret);
+ return ret;
+}
+
+static int
+api_ikev2_profile_set_ts (vat_main_t * vam)
+{
+ unformat_input_t *i = vam->input;
+ vl_api_ikev2_profile_set_ts_t *mp;
+ u8 *name = 0;
+ u8 is_local = 0;
+ u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
+ ip4_address_t start_addr, end_addr;
+
+ const char *valid_chars = "a-zA-Z0-9_";
+ int ret;
+
+ start_addr.as_u32 = 0;
+ end_addr.as_u32 = (u32) ~ 0;
+
+ while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
+ {
+ if (unformat (i, "name %U", unformat_token, valid_chars, &name))
+ vec_add1 (name, 0);
+ else if (unformat (i, "protocol %d", &proto))
+ ;
+ else if (unformat (i, "start_port %d", &start_port))
+ ;
+ else if (unformat (i, "end_port %d", &end_port))
+ ;
+ else
+ if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
+ ;
+ else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
+ ;
+ else if (unformat (i, "local"))
+ is_local = 1;
+ else if (unformat (i, "remote"))
+ is_local = 0;
+ else
+ {
+ errmsg ("parse error '%U'", format_unformat_error, i);
+ return -99;
+ }
+ }
+
+ if (!vec_len (name))
+ {
+ errmsg ("profile name must be specified");
+ return -99;
+ }
+
+ if (vec_len (name) > 64)
+ {
+ errmsg ("profile name too long");
+ return -99;
+ }
+
+ M (IKEV2_PROFILE_SET_TS, mp);
+
+ mp->is_local = is_local;
+ mp->proto = (u8) proto;
+ mp->start_port = (u16) start_port;
+ mp->end_port = (u16) end_port;
+ mp->start_addr = start_addr.as_u32;
+ mp->end_addr = end_addr.as_u32;
+ clib_memcpy (mp->name, name, vec_len (name));
+ vec_free (name);
+
+ S (mp);
+ W (ret);
+ return ret;