- 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;
-}
-
-uword
-unformat_qos_source (unformat_input_t * input, va_list * args)
-{
- int *qs = va_arg (*args, int *);
-
- if (unformat (input, "ip"))
- *qs = QOS_SOURCE_IP;
- else if (unformat (input, "mpls"))
- *qs = QOS_SOURCE_MPLS;
- else if (unformat (input, "ext"))
- *qs = QOS_SOURCE_EXT;
- else if (unformat (input, "vlan"))
- *qs = QOS_SOURCE_VLAN;
- else
- return 0;
-
- 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);
- mp->match_len = ntohl (vec_len (match));
- 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);