- mp->is_add = is_add;
- mp->del_chain = del_chain;
- mp->table_index = ntohl (table_index);
- mp->nbuckets = ntohl (nbuckets);
- mp->memory_size = ntohl (memory_size);
- mp->skip_n_vectors = ntohl (skip);
- mp->match_n_vectors = ntohl (match);
- mp->next_table_index = ntohl (next_table_index);
- mp->miss_next_index = ntohl (miss_next_index);
- mp->current_data_flag = ntohl (current_data_flag);
- mp->current_data_offset = ntohl (current_data_offset);
- clib_memcpy (mp->mask, mask, vec_len (mask));
-
- vec_free (mask);
-
- S (mp);
- W (ret);
- return ret;
-}
-
-#if VPP_API_TEST_BUILTIN == 0
-uword
-unformat_l4_match (unformat_input_t * input, va_list * args)
-{
- u8 **matchp = va_arg (*args, u8 **);
-
- u8 *proto_header = 0;
- int src_port = 0;
- int dst_port = 0;
-
- tcpudp_header_t h;
-
- while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
- {
- if (unformat (input, "src_port %d", &src_port))
- ;
- else if (unformat (input, "dst_port %d", &dst_port))
- ;
- else
- return 0;
- }
-
- h.src_port = clib_host_to_net_u16 (src_port);
- h.dst_port = clib_host_to_net_u16 (dst_port);
- vec_validate (proto_header, sizeof (h) - 1);
- memcpy (proto_header, &h, sizeof (h));
-
- *matchp = proto_header;
-
- return 1;
-}
-
-uword
-unformat_ip4_match (unformat_input_t * input, va_list * args)
-{
- u8 **matchp = va_arg (*args, u8 **);
- u8 *match = 0;
- ip4_header_t *ip;
- int version = 0;
- u32 version_val;
- int hdr_length = 0;
- u32 hdr_length_val;
- int src = 0, dst = 0;
- ip4_address_t src_val, dst_val;
- int proto = 0;
- u32 proto_val;
- int tos = 0;
- u32 tos_val;
- int length = 0;
- u32 length_val;
- int fragment_id = 0;
- u32 fragment_id_val;
- int ttl = 0;
- int ttl_val;
- int checksum = 0;
- u32 checksum_val;
-
- while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
- {
- if (unformat (input, "version %d", &version_val))
- version = 1;
- else if (unformat (input, "hdr_length %d", &hdr_length_val))
- hdr_length = 1;
- else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
- src = 1;
- else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
- dst = 1;
- else if (unformat (input, "proto %d", &proto_val))
- proto = 1;
- else if (unformat (input, "tos %d", &tos_val))
- tos = 1;
- else if (unformat (input, "length %d", &length_val))
- length = 1;
- else if (unformat (input, "fragment_id %d", &fragment_id_val))
- fragment_id = 1;
- else if (unformat (input, "ttl %d", &ttl_val))
- ttl = 1;
- else if (unformat (input, "checksum %d", &checksum_val))
- checksum = 1;
- else
- break;
- }
-
- if (version + hdr_length + src + dst + proto + tos + length + fragment_id
- + ttl + checksum == 0)
- return 0;
-
- /*
- * Aligned because we use the real comparison functions
- */
- vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
-
- ip = (ip4_header_t *) match;
-
- /* These are realistically matched in practice */
- if (src)
- ip->src_address.as_u32 = src_val.as_u32;
-
- if (dst)
- ip->dst_address.as_u32 = dst_val.as_u32;
-
- if (proto)
- ip->protocol = proto_val;
-
-
- /* These are not, but they're included for completeness */
- if (version)
- ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
-
- if (hdr_length)
- ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
-
- if (tos)
- ip->tos = tos_val;
-
- if (length)
- ip->length = clib_host_to_net_u16 (length_val);
-
- if (ttl)
- ip->ttl = ttl_val;
-
- if (checksum)
- ip->checksum = clib_host_to_net_u16 (checksum_val);
-
- *matchp = match;
- return 1;
-}
-
-uword
-unformat_ip6_match (unformat_input_t * input, va_list * args)
-{
- u8 **matchp = va_arg (*args, u8 **);
- u8 *match = 0;
- ip6_header_t *ip;
- int version = 0;
- u32 version_val;
- u8 traffic_class = 0;
- u32 traffic_class_val = 0;
- u8 flow_label = 0;
- u8 flow_label_val;
- int src = 0, dst = 0;
- ip6_address_t src_val, dst_val;
- int proto = 0;
- u32 proto_val;
- int payload_length = 0;
- u32 payload_length_val;
- int hop_limit = 0;
- int hop_limit_val;
- u32 ip_version_traffic_class_and_flow_label;
-
- while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
- {
- if (unformat (input, "version %d", &version_val))
- version = 1;
- else if (unformat (input, "traffic_class %d", &traffic_class_val))
- traffic_class = 1;
- else if (unformat (input, "flow_label %d", &flow_label_val))
- flow_label = 1;
- else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
- src = 1;
- else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
- dst = 1;
- else if (unformat (input, "proto %d", &proto_val))
- proto = 1;
- else if (unformat (input, "payload_length %d", &payload_length_val))
- payload_length = 1;
- else if (unformat (input, "hop_limit %d", &hop_limit_val))
- hop_limit = 1;
- else
- break;
- }
-
- if (version + traffic_class + flow_label + src + dst + proto +
- payload_length + hop_limit == 0)
- return 0;
-
- /*
- * Aligned because we use the real comparison functions
- */
- vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
-
- ip = (ip6_header_t *) match;
-
- if (src)
- clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
-
- if (dst)
- clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
-
- if (proto)
- ip->protocol = proto_val;
-
- ip_version_traffic_class_and_flow_label = 0;
-
- if (version)
- ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
-
- if (traffic_class)
- ip_version_traffic_class_and_flow_label |=
- (traffic_class_val & 0xFF) << 20;
-
- if (flow_label)
- ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
-
- ip->ip_version_traffic_class_and_flow_label =
- clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
-
- if (payload_length)
- ip->payload_length = clib_host_to_net_u16 (payload_length_val);
-
- if (hop_limit)
- ip->hop_limit = hop_limit_val;
-
- *matchp = match;
- return 1;
-}
-
-uword
-unformat_l3_match (unformat_input_t * input, va_list * args)
-{
- u8 **matchp = va_arg (*args, u8 **);
-
- while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
- {
- if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
- return 1;
- else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
- return 1;
- else
- break;
- }
- return 0;
-}
-
-uword
-unformat_vlan_tag (unformat_input_t * input, va_list * args)
-{
- u8 *tagp = va_arg (*args, u8 *);
- u32 tag;
-
- if (unformat (input, "%d", &tag))
- {
- tagp[0] = (tag >> 8) & 0x0F;
- tagp[1] = tag & 0xFF;
- return 1;
- }
-
- return 0;
-}
-
-uword
-unformat_l2_match (unformat_input_t * input, va_list * args)
-{
- u8 **matchp = va_arg (*args, u8 **);
- u8 *match = 0;
- u8 src = 0;
- u8 src_val[6];
- u8 dst = 0;
- u8 dst_val[6];
- u8 proto = 0;
- u16 proto_val;
- u8 tag1 = 0;
- u8 tag1_val[2];
- u8 tag2 = 0;
- u8 tag2_val[2];
- int len = 14;
- u8 ignore_tag1 = 0;
- u8 ignore_tag2 = 0;
- u8 cos1 = 0;
- u8 cos2 = 0;
- u32 cos1_val = 0;
- u32 cos2_val = 0;
-
- while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
- {
- if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
- src = 1;
- else
- if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
- dst = 1;
- else if (unformat (input, "proto %U",
- unformat_ethernet_type_host_byte_order, &proto_val))
- proto = 1;
- else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
- tag1 = 1;
- else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
- tag2 = 1;
- else if (unformat (input, "ignore-tag1"))
- ignore_tag1 = 1;
- else if (unformat (input, "ignore-tag2"))
- ignore_tag2 = 1;
- else if (unformat (input, "cos1 %d", &cos1_val))
- cos1 = 1;
- else if (unformat (input, "cos2 %d", &cos2_val))
- cos2 = 1;
- else
- break;
- }
- if ((src + dst + proto + tag1 + tag2 +
- ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
- return 0;
-
- if (tag1 || ignore_tag1 || cos1)
- len = 18;
- if (tag2 || ignore_tag2 || cos2)
- len = 22;
-
- vec_validate_aligned (match, len - 1, sizeof (u32x4));
-
- if (dst)
- clib_memcpy (match, dst_val, 6);
-
- if (src)
- clib_memcpy (match + 6, src_val, 6);
-
- if (tag2)
- {
- /* inner vlan tag */
- match[19] = tag2_val[1];
- match[18] = tag2_val[0];
- if (cos2)
- match[18] |= (cos2_val & 0x7) << 5;
- if (proto)
- {
- match[21] = proto_val & 0xff;
- match[20] = proto_val >> 8;
- }
- if (tag1)
- {
- match[15] = tag1_val[1];
- match[14] = tag1_val[0];
- }
- if (cos1)
- match[14] |= (cos1_val & 0x7) << 5;
- *matchp = match;
- return 1;
- }
- if (tag1)
- {
- match[15] = tag1_val[1];
- match[14] = tag1_val[0];
- if (proto)
- {
- match[17] = proto_val & 0xff;
- match[16] = proto_val >> 8;
- }
- if (cos1)
- match[14] |= (cos1_val & 0x7) << 5;
-
- *matchp = match;
- return 1;
- }
- if (cos2)
- match[18] |= (cos2_val & 0x7) << 5;
- if (cos1)
- match[14] |= (cos1_val & 0x7) << 5;
- if (proto)
- {
- match[13] = proto_val & 0xff;
- match[12] = proto_val >> 8;
- }
-
- *matchp = match;
- return 1;
-}
-#endif
-
-uword
-api_unformat_classify_match (unformat_input_t * input, va_list * args)
-{
- u8 **matchp = va_arg (*args, u8 **);
- u32 skip_n_vectors = va_arg (*args, u32);
- u32 match_n_vectors = va_arg (*args, u32);
-
- u8 *match = 0;
- u8 *l2 = 0;
- u8 *l3 = 0;
- u8 *l4 = 0;
-
- while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
- {
- if (unformat (input, "hex %U", unformat_hex_string, &match))
- ;
- else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
- ;
- else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
- ;
- else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
- ;
- else
- break;
- }
-
- if (l4 && !l3)
- {
- vec_free (match);
- vec_free (l2);
- vec_free (l4);
- return 0;
- }
-
- if (match || l2 || l3 || l4)
- {
- if (l2 || l3 || l4)
- {
- /* "Win a free Ethernet header in every packet" */
- if (l2 == 0)
- vec_validate_aligned (l2, 13, sizeof (u32x4));
- match = l2;
- if (vec_len (l3))
- {
- vec_append_aligned (match, l3, sizeof (u32x4));
- vec_free (l3);
- }
- if (vec_len (l4))
- {
- vec_append_aligned (match, l4, sizeof (u32x4));
- vec_free (l4);
- }
- }
-
- /* Make sure the vector is big enough even if key is all 0's */
- vec_validate_aligned
- (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
- sizeof (u32x4));
-
- /* Set size, include skipped vectors */
- _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
-
- *matchp = match;
-
- return 1;
- }
-
- return 0;
-}
-
-static int
-api_classify_add_del_session (vat_main_t * vam)
-{
- unformat_input_t *i = vam->input;
- vl_api_classify_add_del_session_t *mp;
- int is_add = 1;
- u32 table_index = ~0;
- u32 hit_next_index = ~0;
- u32 opaque_index = ~0;
- u8 *match = 0;
- i32 advance = 0;
- u32 skip_n_vectors = 0;
- u32 match_n_vectors = 0;
- u32 action = 0;
- u32 metadata = 0;
- int ret;
-
- /*
- * Warning: you have to supply skip_n and match_n
- * because the API client cant simply look at the classify
- * table object.
- */
-
- while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
- {
- if (unformat (i, "del"))
- is_add = 0;
- else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
- &hit_next_index))
- ;
- else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
- &hit_next_index))
- ;
- else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
- &hit_next_index))
- ;
- else if (unformat (i, "policer-hit-next %d", &hit_next_index))
- ;
- else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
- ;
- else if (unformat (i, "opaque-index %d", &opaque_index))
- ;
- else if (unformat (i, "skip_n %d", &skip_n_vectors))
- ;
- else if (unformat (i, "match_n %d", &match_n_vectors))
- ;
- else if (unformat (i, "match %U", api_unformat_classify_match,
- &match, skip_n_vectors, match_n_vectors))
- ;
- else if (unformat (i, "advance %d", &advance))
- ;
- else if (unformat (i, "table-index %d", &table_index))
- ;
- else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
- action = 1;
- else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
- action = 2;
- else if (unformat (i, "action %d", &action))
- ;
- else if (unformat (i, "metadata %d", &metadata))
- ;
- else
- break;
- }
-
- if (table_index == ~0)
- {
- errmsg ("Table index required");
- return -99;
- }
-
- if (is_add && match == 0)
- {
- errmsg ("Match value required");
- return -99;
- }
-
- M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
-
- mp->is_add = is_add;
- mp->table_index = ntohl (table_index);
- mp->hit_next_index = ntohl (hit_next_index);
- mp->opaque_index = ntohl (opaque_index);
- mp->advance = ntohl (advance);
- mp->action = action;
- mp->metadata = ntohl (metadata);
- clib_memcpy (mp->match, match, vec_len (match));
- vec_free (match);
-
- S (mp);
- W (ret);
- return ret;
-}
-
-static int
-api_classify_set_interface_ip_table (vat_main_t * vam)
-{
- unformat_input_t *i = vam->input;
- vl_api_classify_set_interface_ip_table_t *mp;
- u32 sw_if_index;
- int sw_if_index_set;
- u32 table_index = ~0;
- u8 is_ipv6 = 0;
- 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, "table %d", &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 (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
-
- mp->sw_if_index = ntohl (sw_if_index);
- mp->table_index = ntohl (table_index);
- mp->is_ipv6 = is_ipv6;
-
- S (mp);
- W (ret);
- return ret;
-}
-
-static int
-api_classify_set_interface_l2_tables (vat_main_t * vam)
-{
- unformat_input_t *i = vam->input;
- vl_api_classify_set_interface_l2_tables_t *mp;
- u32 sw_if_index;
- int sw_if_index_set;
- u32 ip4_table_index = ~0;
- u32 ip6_table_index = ~0;
- u32 other_table_index = ~0;
- u32 is_input = 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, "ip4-table %d", &ip4_table_index))
- ;
- else if (unformat (i, "ip6-table %d", &ip6_table_index))
- ;
- else if (unformat (i, "other-table %d", &other_table_index))
- ;
- else if (unformat (i, "is-input %d", &is_input))
- ;
- 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 (CLASSIFY_SET_INTERFACE_L2_TABLES, 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->other_table_index = ntohl (other_table_index);
- mp->is_input = (u8) is_input;
-
- S (mp);
- W (ret);
- return ret;
-}
-
-static int
-api_set_ipfix_exporter (vat_main_t * vam)
-{
- unformat_input_t *i = vam->input;
- vl_api_set_ipfix_exporter_t *mp;
- ip4_address_t collector_address;
- u8 collector_address_set = 0;
- u32 collector_port = ~0;
- ip4_address_t src_address;
- u8 src_address_set = 0;
- u32 vrf_id = ~0;
- u32 path_mtu = ~0;
- u32 template_interval = ~0;
- u8 udp_checksum = 0;
- int ret;
-
- while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
- {
- if (unformat (i, "collector_address %U", unformat_ip4_address,
- &collector_address))
- collector_address_set = 1;
- else if (unformat (i, "collector_port %d", &collector_port))
- ;
- else if (unformat (i, "src_address %U", unformat_ip4_address,
- &src_address))
- src_address_set = 1;
- else if (unformat (i, "vrf_id %d", &vrf_id))
- ;
- else if (unformat (i, "path_mtu %d", &path_mtu))
- ;
- else if (unformat (i, "template_interval %d", &template_interval))
- ;
- else if (unformat (i, "udp_checksum"))
- udp_checksum = 1;
- else
- break;
- }
-
- if (collector_address_set == 0)
- {
- errmsg ("collector_address required");
- return -99;
- }
-
- if (src_address_set == 0)
- {
- errmsg ("src_address required");
- return -99;
- }
-
- M (SET_IPFIX_EXPORTER, mp);
-
- memcpy (mp->collector_address, collector_address.data,
- sizeof (collector_address.data));
- mp->collector_port = htons ((u16) collector_port);
- memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
- mp->vrf_id = htonl (vrf_id);
- mp->path_mtu = htonl (path_mtu);
- mp->template_interval = htonl (template_interval);
- mp->udp_checksum = udp_checksum;
-
- S (mp);
- W (ret);
- return ret;
-}
-
-static int
-api_set_ipfix_classify_stream (vat_main_t * vam)
-{
- unformat_input_t *i = vam->input;
- vl_api_set_ipfix_classify_stream_t *mp;
- u32 domain_id = 0;
- u32 src_port = UDP_DST_PORT_ipfix;
- int ret;
-
- while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
- {
- if (unformat (i, "domain %d", &domain_id))
- ;
- else if (unformat (i, "src_port %d", &src_port))
- ;
- else
- {
- errmsg ("unknown input `%U'", format_unformat_error, i);
- return -99;
- }
- }
-
- M (SET_IPFIX_CLASSIFY_STREAM, mp);
-
- mp->domain_id = htonl (domain_id);
- mp->src_port = htons ((u16) src_port);
-
- S (mp);
- W (ret);
- return ret;
-}
-
-static int
-api_ipfix_classify_table_add_del (vat_main_t * vam)
-{
- unformat_input_t *i = vam->input;
- vl_api_ipfix_classify_table_add_del_t *mp;
- int is_add = -1;
- u32 classify_table_index = ~0;
- u8 ip_version = 0;
- u8 transport_protocol = 255;
- int ret;
-
- while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
- {
- if (unformat (i, "add"))
- is_add = 1;
- else if (unformat (i, "del"))
- is_add = 0;
- else if (unformat (i, "table %d", &classify_table_index))
- ;
- else if (unformat (i, "ip4"))
- ip_version = 4;
- else if (unformat (i, "ip6"))
- ip_version = 6;
- else if (unformat (i, "tcp"))
- transport_protocol = 6;
- else if (unformat (i, "udp"))
- transport_protocol = 17;
- else
- {
- errmsg ("unknown input `%U'", format_unformat_error, i);
- return -99;
- }
- }
-
- if (is_add == -1)
- {
- errmsg ("expecting: add|del");
- return -99;
- }
- if (classify_table_index == ~0)
- {
- errmsg ("classifier table not specified");
- return -99;
- }
- if (ip_version == 0)
- {
- errmsg ("IP version not specified");
- return -99;
- }
-
- M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
-
- mp->is_add = is_add;
- mp->table_id = htonl (classify_table_index);
- mp->ip_version = ip_version;
- mp->transport_protocol = transport_protocol;
-
- S (mp);
- W (ret);
- return ret;
-}
-
-static int
-api_get_node_index (vat_main_t * vam)
-{
- unformat_input_t *i = vam->input;
- vl_api_get_node_index_t *mp;
- u8 *name = 0;
- int ret;
-
- while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
- {
- if (unformat (i, "node %s", &name))
- ;
- else
- break;
- }
- if (name == 0)
- {
- errmsg ("node name required");
- return -99;
- }
- if (vec_len (name) >= ARRAY_LEN (mp->node_name))
- {
- errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
- return -99;
- }
-
- M (GET_NODE_INDEX, mp);
- clib_memcpy (mp->node_name, name, vec_len (name));
- vec_free (name);
-
- S (mp);
- W (ret);
- return ret;
-}
-
-static int
-api_get_next_index (vat_main_t * vam)
-{
- unformat_input_t *i = vam->input;
- vl_api_get_next_index_t *mp;
- u8 *node_name = 0, *next_node_name = 0;
- int ret;
-
- while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
- {
- if (unformat (i, "node-name %s", &node_name))
- ;
- else if (unformat (i, "next-node-name %s", &next_node_name))
- break;
- }
-
- if (node_name == 0)
- {
- errmsg ("node name required");
- return -99;
- }
- if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
- {
- errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
- return -99;
- }
-
- if (next_node_name == 0)
- {
- errmsg ("next node name required");
- return -99;
- }
- if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
- {
- errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
- return -99;
- }
-
- M (GET_NEXT_INDEX, mp);
- clib_memcpy (mp->node_name, node_name, vec_len (node_name));
- clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
- vec_free (node_name);
- vec_free (next_node_name);
-
- S (mp);
- W (ret);
- return ret;
-}
-
-static int
-api_add_node_next (vat_main_t * vam)
-{
- unformat_input_t *i = vam->input;
- vl_api_add_node_next_t *mp;
- u8 *name = 0;
- u8 *next = 0;
- int ret;
-
- while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
- {
- if (unformat (i, "node %s", &name))
- ;
- else if (unformat (i, "next %s", &next))
- ;
- else
- break;
- }
- if (name == 0)
- {
- errmsg ("node name required");
- return -99;
- }
- if (vec_len (name) >= ARRAY_LEN (mp->node_name))
- {
- errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
- return -99;
- }
- if (next == 0)
- {
- errmsg ("next node required");
- return -99;
- }
- if (vec_len (next) >= ARRAY_LEN (mp->next_name))
- {
- errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
- return -99;
- }
-
- M (ADD_NODE_NEXT, mp);
- clib_memcpy (mp->node_name, name, vec_len (name));
- clib_memcpy (mp->next_name, next, vec_len (next));
- vec_free (name);
- vec_free (next);
-
- S (mp);
- W (ret);
- return ret;
-}
-
-static int
-api_l2tpv3_create_tunnel (vat_main_t * vam)
-{
- unformat_input_t *i = vam->input;
- ip6_address_t client_address, our_address;
- int client_address_set = 0;
- int our_address_set = 0;
- u32 local_session_id = 0;
- u32 remote_session_id = 0;
- u64 local_cookie = 0;
- u64 remote_cookie = 0;
- u8 l2_sublayer_present = 0;
- vl_api_l2tpv3_create_tunnel_t *mp;
- int ret;
-
- while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
- {
- if (unformat (i, "client_address %U", unformat_ip6_address,
- &client_address))
- client_address_set = 1;
- else if (unformat (i, "our_address %U", unformat_ip6_address,
- &our_address))
- our_address_set = 1;
- else if (unformat (i, "local_session_id %d", &local_session_id))
- ;
- else if (unformat (i, "remote_session_id %d", &remote_session_id))
- ;
- else if (unformat (i, "local_cookie %lld", &local_cookie))
- ;
- else if (unformat (i, "remote_cookie %lld", &remote_cookie))
- ;
- else if (unformat (i, "l2-sublayer-present"))
- l2_sublayer_present = 1;
- else
- break;
- }
-
- if (client_address_set == 0)
- {
- errmsg ("client_address required");
- return -99;
- }
-
- if (our_address_set == 0)
- {
- errmsg ("our_address required");
- return -99;
- }
-
- M (L2TPV3_CREATE_TUNNEL, mp);
-
- clib_memcpy (mp->client_address, client_address.as_u8,
- sizeof (mp->client_address));
-
- clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
-
- mp->local_session_id = ntohl (local_session_id);
- mp->remote_session_id = ntohl (remote_session_id);
- mp->local_cookie = clib_host_to_net_u64 (local_cookie);
- mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
- mp->l2_sublayer_present = l2_sublayer_present;
- mp->is_ipv6 = 1;
-
- S (mp);
- W (ret);
- return ret;
-}
-
-static int
-api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
-{
- unformat_input_t *i = vam->input;
- u32 sw_if_index;
- u8 sw_if_index_set = 0;
- u64 new_local_cookie = 0;
- u64 new_remote_cookie = 0;
- vl_api_l2tpv3_set_tunnel_cookies_t *mp;
- 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, "new_local_cookie %lld", &new_local_cookie))
- ;
- else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
- ;
- else
- break;
- }
-
- if (sw_if_index_set == 0)
- {
- errmsg ("missing interface name or sw_if_index");
- return -99;
- }
-
- M (L2TPV3_SET_TUNNEL_COOKIES, mp);
-
- mp->sw_if_index = ntohl (sw_if_index);
- mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
- mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
-
- S (mp);
- W (ret);
- return ret;
-}
-
-static int
-api_l2tpv3_interface_enable_disable (vat_main_t * vam)
-{
- unformat_input_t *i = vam->input;
- vl_api_l2tpv3_interface_enable_disable_t *mp;
- u32 sw_if_index;
- u8 sw_if_index_set = 0;
- u8 enable_disable = 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, "enable"))
- enable_disable = 1;
- else if (unformat (i, "disable"))
- enable_disable = 0;
- else
- break;
- }
-
- if (sw_if_index_set == 0)
- {
- errmsg ("missing interface name or sw_if_index");
- return -99;
- }
-
- M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
-
- mp->sw_if_index = ntohl (sw_if_index);
- mp->enable_disable = enable_disable;
-
- S (mp);
- W (ret);
- return ret;
-}
-
-static int
-api_l2tpv3_set_lookup_key (vat_main_t * vam)
-{
- unformat_input_t *i = vam->input;
- vl_api_l2tpv3_set_lookup_key_t *mp;
- u8 key = ~0;
- int ret;
-
- while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
- {
- if (unformat (i, "lookup_v6_src"))
- key = L2T_LOOKUP_SRC_ADDRESS;
- else if (unformat (i, "lookup_v6_dst"))
- key = L2T_LOOKUP_DST_ADDRESS;
- else if (unformat (i, "lookup_session_id"))
- key = L2T_LOOKUP_SESSION_ID;
- else
- break;
- }
-
- if (key == (u8) ~ 0)
- {
- errmsg ("l2tp session lookup key unset");
- return -99;
- }
-
- M (L2TPV3_SET_LOOKUP_KEY, mp);
-
- mp->key = key;
-
- S (mp);
- W (ret);
- return ret;
-}
-
-static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
- (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
-{
- vat_main_t *vam = &vat_main;
-
- print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
- format_ip6_address, mp->our_address,
- format_ip6_address, mp->client_address,
- clib_net_to_host_u32 (mp->sw_if_index));
-
- print (vam->ofp,
- " local cookies %016llx %016llx remote cookie %016llx",
- clib_net_to_host_u64 (mp->local_cookie[0]),
- clib_net_to_host_u64 (mp->local_cookie[1]),
- clib_net_to_host_u64 (mp->remote_cookie));
-
- print (vam->ofp, " local session-id %d remote session-id %d",
- clib_net_to_host_u32 (mp->local_session_id),
- clib_net_to_host_u32 (mp->remote_session_id));
-
- print (vam->ofp, " l2 specific sublayer %s\n",
- mp->l2_sublayer_present ? "preset" : "absent");
-
-}
-
-static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
- (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
-{
- vat_main_t *vam = &vat_main;
- vat_json_node_t *node = NULL;
- struct in6_addr addr;
-
- if (VAT_JSON_ARRAY != vam->json_tree.type)
- {
- ASSERT (VAT_JSON_NONE == vam->json_tree.type);
- vat_json_init_array (&vam->json_tree);
- }
- node = vat_json_array_add (&vam->json_tree);
-
- vat_json_init_object (node);
-
- clib_memcpy (&addr, mp->our_address, sizeof (addr));
- vat_json_object_add_ip6 (node, "our_address", addr);
- clib_memcpy (&addr, mp->client_address, sizeof (addr));
- vat_json_object_add_ip6 (node, "client_address", addr);
-
- vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
- vat_json_init_array (lc);
- vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
- vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
- vat_json_object_add_uint (node, "remote_cookie",
- clib_net_to_host_u64 (mp->remote_cookie));
-
- printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
- vat_json_object_add_uint (node, "local_session_id",
- clib_net_to_host_u32 (mp->local_session_id));
- vat_json_object_add_uint (node, "remote_session_id",
- clib_net_to_host_u32 (mp->remote_session_id));
- vat_json_object_add_string_copy (node, "l2_sublayer",
- mp->l2_sublayer_present ? (u8 *) "present"
- : (u8 *) "absent");
-}
-
-static int
-api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
-{
- vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
- vl_api_control_ping_t *mp_ping;
- int ret;
-
- /* Get list of l2tpv3-tunnel interfaces */
- M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
- S (mp);
-
- /* Use a control ping for synchronization */
- MPING (CONTROL_PING, mp_ping);
- S (mp_ping);
-
- W (ret);
- return ret;
-}
-
-
-static void vl_api_sw_interface_tap_details_t_handler
- (vl_api_sw_interface_tap_details_t * mp)
-{
- vat_main_t *vam = &vat_main;
-
- print (vam->ofp, "%-16s %d",
- mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
-}
-
-static void vl_api_sw_interface_tap_details_t_handler_json
- (vl_api_sw_interface_tap_details_t * mp)
-{
- vat_main_t *vam = &vat_main;
- vat_json_node_t *node = NULL;
-
- if (VAT_JSON_ARRAY != vam->json_tree.type)
- {
- ASSERT (VAT_JSON_NONE == vam->json_tree.type);
- vat_json_init_array (&vam->json_tree);
- }
- node = vat_json_array_add (&vam->json_tree);
-
- vat_json_init_object (node);
- vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
- vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
-}
-
-static int
-api_sw_interface_tap_dump (vat_main_t * vam)
-{
- vl_api_sw_interface_tap_dump_t *mp;
- vl_api_control_ping_t *mp_ping;
- int ret;
-
- print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
- /* Get list of tap interfaces */
- M (SW_INTERFACE_TAP_DUMP, mp);
- S (mp);
-
- /* Use a control ping for synchronization */
- MPING (CONTROL_PING, mp_ping);
- S (mp_ping);
-
- W (ret);
- return ret;
-}
-
-static uword unformat_vxlan_decap_next
- (unformat_input_t * input, va_list * args)
-{
- u32 *result = va_arg (*args, u32 *);
- u32 tmp;
-
- if (unformat (input, "l2"))
- *result = VXLAN_INPUT_NEXT_L2_INPUT;
- else if (unformat (input, "%d", &tmp))
- *result = tmp;
- else
- return 0;
- return 1;
-}
-
-static int
-api_vxlan_add_del_tunnel (vat_main_t * vam)
-{
- unformat_input_t *line_input = vam->input;
- vl_api_vxlan_add_del_tunnel_t *mp;
- ip46_address_t src, dst;
- u8 is_add = 1;
- u8 ipv4_set = 0, ipv6_set = 0;
- u8 src_set = 0;
- u8 dst_set = 0;
- u8 grp_set = 0;
- u32 mcast_sw_if_index = ~0;
- u32 encap_vrf_id = 0;
- u32 decap_next_index = ~0;
- u32 vni = 0;
- int ret;
-
- /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
- memset (&src, 0, sizeof src);
- memset (&dst, 0, sizeof dst);
-
- while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
- {
- if (unformat (line_input, "del"))
- is_add = 0;
- else
- if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
- {
- ipv4_set = 1;
- src_set = 1;
- }
- else
- if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
- {
- ipv4_set = 1;
- dst_set = 1;
- }
- else
- if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
- {
- ipv6_set = 1;
- src_set = 1;
- }
- else
- if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
- {
- ipv6_set = 1;
- dst_set = 1;
- }
- else if (unformat (line_input, "group %U %U",
- unformat_ip4_address, &dst.ip4,
- api_unformat_sw_if_index, vam, &mcast_sw_if_index))
- {
- grp_set = dst_set = 1;
- ipv4_set = 1;
- }
- else if (unformat (line_input, "group %U",
- unformat_ip4_address, &dst.ip4))
- {
- grp_set = dst_set = 1;
- ipv4_set = 1;
- }
- else if (unformat (line_input, "group %U %U",
- unformat_ip6_address, &dst.ip6,
- api_unformat_sw_if_index, vam, &mcast_sw_if_index))
- {
- grp_set = dst_set = 1;
- ipv6_set = 1;
- }
- else if (unformat (line_input, "group %U",
- unformat_ip6_address, &dst.ip6))
- {
- grp_set = dst_set = 1;
- ipv6_set = 1;
- }
- else
- if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
- ;
- else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
- ;
- else if (unformat (line_input, "decap-next %U",
- unformat_vxlan_decap_next, &decap_next_index))
- ;
- else if (unformat (line_input, "vni %d", &vni))
- ;
- else
- {
- errmsg ("parse error '%U'", format_unformat_error, line_input);
- return -99;
- }
- }
-
- if (src_set == 0)
- {
- errmsg ("tunnel src address not specified");
- return -99;
- }
- if (dst_set == 0)
- {
- errmsg ("tunnel dst address not specified");
- return -99;
- }
-
- if (grp_set && !ip46_address_is_multicast (&dst))
- {
- errmsg ("tunnel group address not multicast");
- return -99;
- }
- if (grp_set && mcast_sw_if_index == ~0)
- {
- errmsg ("tunnel nonexistent multicast device");
- return -99;
- }
- if (grp_set == 0 && ip46_address_is_multicast (&dst))
- {
- errmsg ("tunnel dst address must be unicast");
- return -99;
- }
-
-
- if (ipv4_set && ipv6_set)
- {
- errmsg ("both IPv4 and IPv6 addresses specified");
- return -99;
- }
-
- if ((vni == 0) || (vni >> 24))
- {
- errmsg ("vni not specified or out of range");
- return -99;
- }
-
- M (VXLAN_ADD_DEL_TUNNEL, mp);
-
- if (ipv6_set)
- {
- clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
- clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
- }
- else
- {
- clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
- clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
- }
- mp->encap_vrf_id = ntohl (encap_vrf_id);
- mp->decap_next_index = ntohl (decap_next_index);
- mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
- mp->vni = ntohl (vni);
- mp->is_add = is_add;
- mp->is_ipv6 = ipv6_set;
-
- S (mp);
- W (ret);
- return ret;
-}
-
-static void vl_api_vxlan_tunnel_details_t_handler
- (vl_api_vxlan_tunnel_details_t * mp)
-{
- vat_main_t *vam = &vat_main;
- ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
- ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
-
- print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
- ntohl (mp->sw_if_index),
- format_ip46_address, &src, IP46_TYPE_ANY,
- format_ip46_address, &dst, IP46_TYPE_ANY,
- ntohl (mp->encap_vrf_id),
- ntohl (mp->decap_next_index), ntohl (mp->vni),
- ntohl (mp->mcast_sw_if_index));
-}
-
-static void vl_api_vxlan_tunnel_details_t_handler_json
- (vl_api_vxlan_tunnel_details_t * mp)
-{
- vat_main_t *vam = &vat_main;
- vat_json_node_t *node = NULL;
-
- if (VAT_JSON_ARRAY != vam->json_tree.type)
- {
- ASSERT (VAT_JSON_NONE == vam->json_tree.type);
- vat_json_init_array (&vam->json_tree);
- }
- node = vat_json_array_add (&vam->json_tree);
-
- vat_json_init_object (node);
- vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
- if (mp->is_ipv6)
- {
- struct in6_addr ip6;
-
- clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
- vat_json_object_add_ip6 (node, "src_address", ip6);
- clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
- vat_json_object_add_ip6 (node, "dst_address", ip6);
- }
- else
- {
- struct in_addr ip4;
-
- clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
- vat_json_object_add_ip4 (node, "src_address", ip4);
- clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
- vat_json_object_add_ip4 (node, "dst_address", ip4);
- }
- vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
- vat_json_object_add_uint (node, "decap_next_index",
- ntohl (mp->decap_next_index));
- vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
- vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
- vat_json_object_add_uint (node, "mcast_sw_if_index",
- ntohl (mp->mcast_sw_if_index));
-}
-
-static int
-api_vxlan_tunnel_dump (vat_main_t * vam)
-{
- unformat_input_t *i = vam->input;
- vl_api_vxlan_tunnel_dump_t *mp;
- vl_api_control_ping_t *mp_ping;
- u32 sw_if_index;
- u8 sw_if_index_set = 0;
- int ret;
-
- /* Parse args required to build the message */
- 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
- break;
- }
-
- if (sw_if_index_set == 0)
- {
- sw_if_index = ~0;
- }
-
- if (!vam->json_output)
- {
- print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
- "sw_if_index", "src_address", "dst_address",
- "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
- }
-
- /* Get list of vxlan-tunnel interfaces */
- M (VXLAN_TUNNEL_DUMP, mp);
-
- mp->sw_if_index = htonl (sw_if_index);
-
- S (mp);
-
- /* Use a control ping for synchronization */
- MPING (CONTROL_PING, mp_ping);
- S (mp_ping);
-
- W (ret);
- return ret;
-}
-
-static uword unformat_geneve_decap_next
- (unformat_input_t * input, va_list * args)
-{
- u32 *result = va_arg (*args, u32 *);
- u32 tmp;
-
- if (unformat (input, "l2"))
- *result = GENEVE_INPUT_NEXT_L2_INPUT;
- else if (unformat (input, "%d", &tmp))
- *result = tmp;
- else
- return 0;
- return 1;