+ while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
+ {
+ if (unformat (line_input, "learn-limit %d", &learn_limit))
+ ;
+ else if (unformat (line_input, "scan-delay %d", &scan_delay))
+ ;
+ else if (unformat (line_input, "max-entries %d", &max_macs_in_event))
+ ;
+ else if (unformat (line_input, "disable"))
+ enable_disable = 0;
+ else
+ break;
+ }
+
+ M (WANT_L2_MACS_EVENTS, mp);
+ mp->enable_disable = enable_disable;
+ mp->pid = htonl (getpid ());
+ mp->learn_limit = htonl (learn_limit);
+ mp->scan_delay = (u8) scan_delay;
+ mp->max_macs_in_event = (u8) (max_macs_in_event / 10);
+ S (mp);
+ W (ret);
+ return ret;
+}
+
+static int
+api_input_acl_set_interface (vat_main_t * vam)
+{
+ unformat_input_t *i = vam->input;
+ vl_api_input_acl_set_interface_t *mp;
+ u32 sw_if_index;
+ int sw_if_index_set;
+ u32 ip4_table_index = ~0;
+ u32 ip6_table_index = ~0;
+ u32 l2_table_index = ~0;
+ u8 is_add = 1;
+ int ret;
+
+ while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
+ {
+ if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
+ sw_if_index_set = 1;
+ else if (unformat (i, "sw_if_index %d", &sw_if_index))
+ sw_if_index_set = 1;
+ else if (unformat (i, "del"))
+ is_add = 0;
+ else if (unformat (i, "ip4-table %d", &ip4_table_index))
+ ;
+ else if (unformat (i, "ip6-table %d", &ip6_table_index))
+ ;
+ else if (unformat (i, "l2-table %d", &l2_table_index))
+ ;
+ else
+ {
+ clib_warning ("parse error '%U'", format_unformat_error, i);
+ return -99;
+ }
+ }
+
+ if (sw_if_index_set == 0)
+ {
+ errmsg ("missing interface name or sw_if_index");
+ return -99;
+ }
+
+ M (INPUT_ACL_SET_INTERFACE, mp);
+
+ mp->sw_if_index = ntohl (sw_if_index);
+ mp->ip4_table_index = ntohl (ip4_table_index);
+ mp->ip6_table_index = ntohl (ip6_table_index);
+ mp->l2_table_index = ntohl (l2_table_index);
+ mp->is_add = is_add;
+
+ S (mp);
+ W (ret);
+ return ret;
+}
+
+static int
+api_output_acl_set_interface (vat_main_t * vam)
+{
+ unformat_input_t *i = vam->input;
+ vl_api_output_acl_set_interface_t *mp;
+ u32 sw_if_index;
+ int sw_if_index_set;
+ u32 ip4_table_index = ~0;
+ u32 ip6_table_index = ~0;
+ u32 l2_table_index = ~0;
+ u8 is_add = 1;
+ int ret;
+
+ while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
+ {
+ if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
+ sw_if_index_set = 1;
+ else if (unformat (i, "sw_if_index %d", &sw_if_index))
+ sw_if_index_set = 1;
+ else if (unformat (i, "del"))
+ is_add = 0;
+ else if (unformat (i, "ip4-table %d", &ip4_table_index))
+ ;
+ else if (unformat (i, "ip6-table %d", &ip6_table_index))
+ ;
+ else if (unformat (i, "l2-table %d", &l2_table_index))
+ ;
+ else
+ {
+ clib_warning ("parse error '%U'", format_unformat_error, i);
+ return -99;
+ }
+ }
+
+ if (sw_if_index_set == 0)
+ {
+ errmsg ("missing interface name or sw_if_index");
+ return -99;
+ }
+
+ M (OUTPUT_ACL_SET_INTERFACE, mp);
+
+ mp->sw_if_index = ntohl (sw_if_index);
+ mp->ip4_table_index = ntohl (ip4_table_index);
+ mp->ip6_table_index = ntohl (ip6_table_index);
+ mp->l2_table_index = ntohl (l2_table_index);
+ mp->is_add = is_add;
+
+ S (mp);
+ W (ret);
+ return ret;
+}
+
+static int
+api_ip_address_dump (vat_main_t * vam)
+{
+ unformat_input_t *i = vam->input;
+ vl_api_ip_address_dump_t *mp;
+ vl_api_control_ping_t *mp_ping;
+ u32 sw_if_index = ~0;
+ u8 sw_if_index_set = 0;
+ u8 ipv4_set = 0;
+ u8 ipv6_set = 0;
+ int ret;
+
+ while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
+ {
+ if (unformat (i, "sw_if_index %d", &sw_if_index))
+ sw_if_index_set = 1;
+ else
+ if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
+ sw_if_index_set = 1;
+ else if (unformat (i, "ipv4"))
+ ipv4_set = 1;
+ else if (unformat (i, "ipv6"))
+ ipv6_set = 1;
+ else
+ break;
+ }
+
+ if (ipv4_set && ipv6_set)
+ {
+ errmsg ("ipv4 and ipv6 flags cannot be both set");
+ return -99;
+ }
+
+ if ((!ipv4_set) && (!ipv6_set))
+ {
+ errmsg ("no ipv4 nor ipv6 flag set");
+ return -99;
+ }
+
+ if (sw_if_index_set == 0)
+ {
+ errmsg ("missing interface name or sw_if_index");
+ return -99;
+ }
+
+ vam->current_sw_if_index = sw_if_index;
+ vam->is_ipv6 = ipv6_set;
+
+ M (IP_ADDRESS_DUMP, mp);
+ mp->sw_if_index = ntohl (sw_if_index);
+ mp->is_ipv6 = ipv6_set;
+ S (mp);
+
+ /* Use a control ping for synchronization */
+ MPING (CONTROL_PING, mp_ping);
+ S (mp_ping);
+
+ W (ret);
+ return ret;
+}
+
+static int
+api_ip_dump (vat_main_t * vam)
+{
+ vl_api_ip_dump_t *mp;
+ vl_api_control_ping_t *mp_ping;
+ unformat_input_t *in = vam->input;
+ int ipv4_set = 0;
+ int ipv6_set = 0;
+ int is_ipv6;
+ int i;
+ int ret;
+
+ while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
+ {
+ if (unformat (in, "ipv4"))
+ ipv4_set = 1;
+ else if (unformat (in, "ipv6"))
+ ipv6_set = 1;
+ else
+ break;
+ }
+
+ if (ipv4_set && ipv6_set)
+ {
+ errmsg ("ipv4 and ipv6 flags cannot be both set");
+ return -99;
+ }
+
+ if ((!ipv4_set) && (!ipv6_set))
+ {
+ errmsg ("no ipv4 nor ipv6 flag set");
+ return -99;
+ }
+
+ is_ipv6 = ipv6_set;
+ vam->is_ipv6 = is_ipv6;
+
+ /* free old data */
+ for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
+ {
+ vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
+ }
+ vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
+
+ M (IP_DUMP, mp);
+ mp->is_ipv6 = ipv6_set;
+ S (mp);
+
+ /* Use a control ping for synchronization */
+ MPING (CONTROL_PING, mp_ping);
+ S (mp_ping);
+
+ W (ret);
+ return ret;
+}
+
+static int
+api_ipsec_spd_add_del (vat_main_t * vam)
+{
+ unformat_input_t *i = vam->input;
+ vl_api_ipsec_spd_add_del_t *mp;
+ u32 spd_id = ~0;
+ u8 is_add = 1;
+ int ret;
+
+ while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
+ {
+ if (unformat (i, "spd_id %d", &spd_id))
+ ;
+ else if (unformat (i, "del"))
+ is_add = 0;
+ else
+ {
+ clib_warning ("parse error '%U'", format_unformat_error, i);
+ return -99;
+ }
+ }
+ if (spd_id == ~0)
+ {
+ errmsg ("spd_id must be set");
+ return -99;
+ }
+
+ M (IPSEC_SPD_ADD_DEL, mp);
+
+ mp->spd_id = ntohl (spd_id);
+ mp->is_add = is_add;
+
+ S (mp);
+ W (ret);
+ return ret;
+}
+
+static int
+api_ipsec_interface_add_del_spd (vat_main_t * vam)
+{
+ unformat_input_t *i = vam->input;
+ vl_api_ipsec_interface_add_del_spd_t *mp;
+ u32 sw_if_index;
+ u8 sw_if_index_set = 0;
+ u32 spd_id = (u32) ~ 0;
+ u8 is_add = 1;
+ int ret;
+
+ while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
+ {
+ if (unformat (i, "del"))
+ is_add = 0;
+ else if (unformat (i, "spd_id %d", &spd_id))
+ ;
+ else
+ if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
+ sw_if_index_set = 1;
+ else if (unformat (i, "sw_if_index %d", &sw_if_index))
+ sw_if_index_set = 1;
+ else
+ {
+ clib_warning ("parse error '%U'", format_unformat_error, i);
+ return -99;
+ }
+
+ }
+
+ if (spd_id == (u32) ~ 0)
+ {
+ errmsg ("spd_id must be set");
+ return -99;
+ }
+
+ if (sw_if_index_set == 0)
+ {
+ errmsg ("missing interface name or sw_if_index");
+ return -99;
+ }
+
+ M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
+
+ mp->spd_id = ntohl (spd_id);
+ mp->sw_if_index = ntohl (sw_if_index);
+ mp->is_add = is_add;
+
+ S (mp);
+ W (ret);
+ return ret;
+}
+
+static int
+api_ipsec_spd_add_del_entry (vat_main_t * vam)
+{
+ unformat_input_t *i = vam->input;
+ vl_api_ipsec_spd_add_del_entry_t *mp;
+ u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
+ u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
+ i32 priority = 0;
+ u32 rport_start = 0, rport_stop = (u32) ~ 0;
+ u32 lport_start = 0, lport_stop = (u32) ~ 0;
+ ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
+ ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
+ int ret;
+
+ laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
+ laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
+ laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
+ laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
+ laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
+ laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
+
+ while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
+ {
+ if (unformat (i, "del"))
+ is_add = 0;
+ if (unformat (i, "outbound"))
+ is_outbound = 1;
+ if (unformat (i, "inbound"))
+ is_outbound = 0;
+ else if (unformat (i, "spd_id %d", &spd_id))
+ ;
+ else if (unformat (i, "sa_id %d", &sa_id))
+ ;
+ else if (unformat (i, "priority %d", &priority))
+ ;
+ else if (unformat (i, "protocol %d", &protocol))
+ ;
+ else if (unformat (i, "lport_start %d", &lport_start))
+ ;
+ else if (unformat (i, "lport_stop %d", &lport_stop))
+ ;
+ else if (unformat (i, "rport_start %d", &rport_start))
+ ;
+ else if (unformat (i, "rport_stop %d", &rport_stop))
+ ;
+ else
+ if (unformat
+ (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
+ {
+ is_ipv6 = 0;
+ is_ip_any = 0;
+ }
+ else
+ if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
+ {
+ is_ipv6 = 0;
+ is_ip_any = 0;
+ }
+ else
+ if (unformat
+ (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
+ {
+ is_ipv6 = 0;
+ is_ip_any = 0;
+ }
+ else
+ if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
+ {
+ is_ipv6 = 0;
+ is_ip_any = 0;
+ }
+ else
+ if (unformat
+ (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
+ {
+ is_ipv6 = 1;
+ is_ip_any = 0;
+ }
+ else
+ if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
+ {
+ is_ipv6 = 1;
+ is_ip_any = 0;
+ }
+ else
+ if (unformat
+ (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
+ {
+ is_ipv6 = 1;
+ is_ip_any = 0;
+ }
+ else
+ if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
+ {
+ is_ipv6 = 1;
+ is_ip_any = 0;
+ }
+ else
+ if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
+ {
+ if (policy == IPSEC_POLICY_ACTION_RESOLVE)
+ {
+ clib_warning ("unsupported action: 'resolve'");
+ return -99;
+ }
+ }
+ else
+ {
+ clib_warning ("parse error '%U'", format_unformat_error, i);
+ return -99;
+ }
+
+ }
+
+ M (IPSEC_SPD_ADD_DEL_ENTRY, mp);
+
+ mp->spd_id = ntohl (spd_id);
+ mp->priority = ntohl (priority);
+ mp->is_outbound = is_outbound;
+
+ mp->is_ipv6 = is_ipv6;
+ if (is_ipv6 || is_ip_any)
+ {
+ clib_memcpy (mp->remote_address_start, &raddr6_start,
+ sizeof (ip6_address_t));
+ clib_memcpy (mp->remote_address_stop, &raddr6_stop,
+ sizeof (ip6_address_t));
+ clib_memcpy (mp->local_address_start, &laddr6_start,
+ sizeof (ip6_address_t));
+ clib_memcpy (mp->local_address_stop, &laddr6_stop,
+ sizeof (ip6_address_t));
+ }
+ else
+ {
+ clib_memcpy (mp->remote_address_start, &raddr4_start,
+ sizeof (ip4_address_t));
+ clib_memcpy (mp->remote_address_stop, &raddr4_stop,
+ sizeof (ip4_address_t));
+ clib_memcpy (mp->local_address_start, &laddr4_start,
+ sizeof (ip4_address_t));
+ clib_memcpy (mp->local_address_stop, &laddr4_stop,
+ sizeof (ip4_address_t));
+ }
+ mp->protocol = (u8) protocol;
+ mp->local_port_start = ntohs ((u16) lport_start);
+ mp->local_port_stop = ntohs ((u16) lport_stop);
+ mp->remote_port_start = ntohs ((u16) rport_start);
+ mp->remote_port_stop = ntohs ((u16) rport_stop);
+ mp->policy = (u8) policy;
+ mp->sa_id = ntohl (sa_id);
+ mp->is_add = is_add;
+ mp->is_ip_any = is_ip_any;
+ S (mp);
+ W (ret);
+ return ret;
+}
+
+static int
+api_ipsec_sad_add_del_entry (vat_main_t * vam)
+{
+ unformat_input_t *i = vam->input;
+ vl_api_ipsec_sad_add_del_entry_t *mp;
+ u32 sad_id = 0, spi = 0;
+ u8 *ck = 0, *ik = 0;
+ u8 is_add = 1;
+
+ u8 protocol = IPSEC_PROTOCOL_AH;
+ u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
+ u32 crypto_alg = 0, integ_alg = 0;
+ ip4_address_t tun_src4;
+ ip4_address_t tun_dst4;
+ ip6_address_t tun_src6;
+ ip6_address_t tun_dst6;
+ int ret;
+
+ while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
+ {
+ if (unformat (i, "del"))
+ is_add = 0;
+ else if (unformat (i, "sad_id %d", &sad_id))
+ ;
+ else if (unformat (i, "spi %d", &spi))
+ ;
+ else if (unformat (i, "esp"))
+ protocol = IPSEC_PROTOCOL_ESP;
+ else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
+ {
+ is_tunnel = 1;
+ is_tunnel_ipv6 = 0;
+ }
+ else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
+ {
+ is_tunnel = 1;
+ is_tunnel_ipv6 = 0;
+ }
+ else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
+ {
+ is_tunnel = 1;
+ is_tunnel_ipv6 = 1;
+ }
+ else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
+ {
+ is_tunnel = 1;
+ is_tunnel_ipv6 = 1;
+ }
+ else
+ if (unformat
+ (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
+ {
+ if (crypto_alg >= IPSEC_CRYPTO_N_ALG)
+ {
+ clib_warning ("unsupported crypto-alg: '%U'",
+ format_ipsec_crypto_alg, crypto_alg);
+ return -99;
+ }
+ }
+ else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
+ ;
+ else
+ if (unformat
+ (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
+ {
+ if (integ_alg >= IPSEC_INTEG_N_ALG)
+ {
+ clib_warning ("unsupported integ-alg: '%U'",
+ format_ipsec_integ_alg, integ_alg);
+ return -99;
+ }
+ }
+ 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_SAD_ADD_DEL_ENTRY, mp);
+
+ mp->sad_id = ntohl (sad_id);
+ mp->is_add = is_add;
+ mp->protocol = protocol;
+ mp->spi = ntohl (spi);
+ mp->is_tunnel = is_tunnel;
+ mp->is_tunnel_ipv6 = is_tunnel_ipv6;
+ mp->crypto_algorithm = crypto_alg;
+ mp->integrity_algorithm = integ_alg;
+ 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);
+
+ if (is_tunnel)