X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fvnet%2Fclassify%2Fclassify_api.c;h=7c08528f58a8d4f8b9346d412879de1c6cd1d78e;hb=f3b5d702c11bb2b1c1691c155fd620d65d1fd4ce;hp=77a8b43464ae915bf923f9505ed296990b62a551;hpb=d2c97d988b2fbc28f0905d1826b428967d09348a;p=vpp.git diff --git a/src/vnet/classify/classify_api.c b/src/vnet/classify/classify_api.c index 77a8b43464a..7c08528f58a 100644 --- a/src/vnet/classify/classify_api.c +++ b/src/vnet/classify/classify_api.c @@ -24,9 +24,12 @@ #include #include -#include +#include #include #include +#include +#include +#include #include @@ -49,15 +52,25 @@ #define foreach_vpe_api_msg \ _(CLASSIFY_ADD_DEL_TABLE, classify_add_del_table) \ _(CLASSIFY_ADD_DEL_SESSION, classify_add_del_session) \ -_(CLASSIFY_TABLE_IDS,classify_table_ids) \ +_(CLASSIFY_TABLE_IDS, classify_table_ids) \ _(CLASSIFY_TABLE_BY_INTERFACE, classify_table_by_interface) \ -_(CLASSIFY_TABLE_INFO,classify_table_info) \ -_(CLASSIFY_SESSION_DUMP,classify_session_dump) \ -_(CLASSIFY_SESSION_DETAILS,classify_session_details) \ +_(CLASSIFY_TABLE_INFO, classify_table_info) \ +_(CLASSIFY_SESSION_DUMP, classify_session_dump) \ _(POLICER_CLASSIFY_SET_INTERFACE, policer_classify_set_interface) \ _(POLICER_CLASSIFY_DUMP, policer_classify_dump) \ _(FLOW_CLASSIFY_SET_INTERFACE, flow_classify_set_interface) \ -_(FLOW_CLASSIFY_DUMP, flow_classify_dump) +_(FLOW_CLASSIFY_DUMP, flow_classify_dump) \ +_(INPUT_ACL_SET_INTERFACE, input_acl_set_interface) \ +_(CLASSIFY_SET_INTERFACE_IP_TABLE, classify_set_interface_ip_table) \ +_(CLASSIFY_SET_INTERFACE_L2_TABLES, classify_set_interface_l2_tables) \ +_(OUTPUT_ACL_SET_INTERFACE, output_acl_set_interface) \ +_(CLASSIFY_PCAP_LOOKUP_TABLE, classify_pcap_lookup_table) \ +_(CLASSIFY_PCAP_SET_TABLE, classify_pcap_set_table) \ +_(CLASSIFY_PCAP_GET_TABLES, classify_pcap_get_tables) \ +_(CLASSIFY_TRACE_LOOKUP_TABLE, classify_trace_lookup_table) \ +_(CLASSIFY_TRACE_SET_TABLE, classify_trace_set_table) \ +_(CLASSIFY_TRACE_GET_TABLES, classify_trace_get_tables) \ + #define foreach_classify_add_del_table_field \ _(table_index) \ @@ -67,8 +80,285 @@ _(skip_n_vectors) \ _(match_n_vectors) \ _(next_table_index) \ _(miss_next_index) \ -_(current_data_flag) \ -_(current_data_offset) +_(mask_len) + + +static void vl_api_classify_pcap_lookup_table_t_handler + (vl_api_classify_pcap_lookup_table_t * mp) +{ + vnet_classify_main_t *cm = &vnet_classify_main; + vl_api_registration_t *reg; + vl_api_classify_pcap_lookup_table_reply_t *rmp; + int rv = 0; + u32 table_index = ~0; + + reg = vl_api_client_index_to_registration (mp->client_index); + if (!reg) + return; + + u32 n_skip = ntohl (mp->skip_n_vectors); + u32 n_match = ntohl (mp->match_n_vectors); + u32 mask_len = ntohl (mp->mask_len); + u32 sw_if_index = ntohl (mp->sw_if_index); + + if (n_skip > 5 || n_match == 0 || n_match > 5 || + mask_len != n_match * sizeof (u32x4) || sw_if_index == ~0 || + sw_if_index >= vec_len (cm->classify_table_index_by_sw_if_index)) + { + rv = VNET_API_ERROR_INVALID_VALUE; + goto out; + } + + u32 table_chain; + table_chain = classify_get_pcap_chain (cm, sw_if_index); + + u8 *mask_vec = 0; + vec_validate (mask_vec, mask_len - 1); + clib_memcpy (mask_vec, mp->mask, mask_len); + + if (table_chain != ~0) + table_index = classify_lookup_chain (table_chain, + mask_vec, n_skip, n_match); + + vec_free (mask_vec); + +out: + rmp = vl_msg_api_alloc (sizeof (*rmp)); + rmp->_vl_msg_id = ntohs (VL_API_CLASSIFY_PCAP_LOOKUP_TABLE_REPLY); + rmp->context = mp->context; + rmp->retval = ntohl (rv); + rmp->table_index = htonl (table_index); + + vl_api_send_msg (reg, (u8 *) rmp); +} + +static void vl_api_classify_pcap_set_table_t_handler + (vl_api_classify_pcap_set_table_t * mp) +{ + vnet_classify_main_t *cm = &vnet_classify_main; + vl_api_classify_pcap_set_table_reply_t *rmp; + vl_api_registration_t *reg; + int rv = 0; + + reg = vl_api_client_index_to_registration (mp->client_index); + if (!reg) + return; + + u32 table_index = ntohl (mp->table_index); + u32 sw_if_index = ntohl (mp->sw_if_index); + + if (sw_if_index == ~0 + || sw_if_index >= vec_len (cm->classify_table_index_by_sw_if_index) + || (table_index != ~0 && pool_is_free_index (cm->tables, table_index))) + { + rv = VNET_API_ERROR_INVALID_VALUE; + goto out; + } + + /* + * Maybe reorder tables such that masks are most-specify to least-specific. + */ + if (table_index != ~0 && mp->sort_masks) + table_index = classify_sort_table_chain (cm, table_index); + + classify_set_pcap_chain (cm, sw_if_index, table_index); + +out: + rmp = vl_msg_api_alloc (sizeof (*rmp)); + rmp->_vl_msg_id = ntohs (VL_API_CLASSIFY_PCAP_SET_TABLE_REPLY); + rmp->context = mp->context; + rmp->retval = ntohl (rv); + rmp->table_index = htonl (table_index); + + vl_api_send_msg (reg, (u8 *) rmp); +} + +static void vl_api_classify_pcap_get_tables_t_handler + (vl_api_classify_pcap_get_tables_t * mp) +{ + vnet_classify_main_t *cm = &vnet_classify_main; + vl_api_classify_pcap_get_tables_reply_t *rmp; + vl_api_registration_t *reg; + int rv = 0; + u32 *tables = 0; + u32 count; + + reg = vl_api_client_index_to_registration (mp->client_index); + if (!reg) + return; + + u32 sw_if_index = ntohl (mp->sw_if_index); + if (sw_if_index == ~0 + || sw_if_index >= vec_len (cm->classify_table_index_by_sw_if_index)) + { + rv = VNET_API_ERROR_INVALID_VALUE; + goto out; + } + + u32 table_index = classify_get_pcap_chain (cm, sw_if_index); + if (table_index == ~0) + goto out; + + /* + * Form a vector of all classifier tables in this chain. + */ + vnet_classify_table_t *t; + u32 i; + + for (i = table_index; i != ~0; i = t->next_table_index) + { + vec_add1 (tables, i); + t = pool_elt_at_index (cm->tables, i); + } + +out: + count = vec_len (tables); + rmp = vl_msg_api_alloc_as_if_client (sizeof (*rmp) + count * sizeof (u32)); + rmp->_vl_msg_id = ntohs (VL_API_CLASSIFY_PCAP_GET_TABLES_REPLY); + rmp->context = mp->context; + rmp->retval = ntohl (rv); + rmp->count = htonl (count); + + for (i = 0; i < count; ++i) + { + rmp->indices[i] = htonl (tables[i]); + } + + vec_free (tables); + + vl_api_send_msg (reg, (u8 *) rmp); +} + + +static void vl_api_classify_trace_lookup_table_t_handler + (vl_api_classify_trace_lookup_table_t * mp) +{ + vl_api_classify_trace_lookup_table_reply_t *rmp; + vl_api_registration_t *reg; + int rv = 0; + u32 table_index = ~0; + + reg = vl_api_client_index_to_registration (mp->client_index); + if (!reg) + return; + + u32 n_skip = ntohl (mp->skip_n_vectors); + u32 n_match = ntohl (mp->match_n_vectors); + u32 mask_len = ntohl (mp->mask_len); + if (n_skip > 5 + || n_match == 0 || n_match > 5 || mask_len != n_match * sizeof (u32x4)) + { + rv = VNET_API_ERROR_INVALID_VALUE; + goto out; + } + + u32 table_chain; + table_chain = classify_get_trace_chain (); + + u8 *mask_vec = 0; + vec_validate (mask_vec, mask_len - 1); + clib_memcpy (mask_vec, mp->mask, mask_len); + + if (table_chain != ~0) + table_index = classify_lookup_chain (table_chain, + mask_vec, n_skip, n_match); + vec_free (mask_vec); + +out: + rmp = vl_msg_api_alloc (sizeof (*rmp)); + rmp->_vl_msg_id = ntohs ((VL_API_CLASSIFY_TRACE_LOOKUP_TABLE_REPLY)); + rmp->context = mp->context; + rmp->retval = ntohl (rv); + rmp->table_index = htonl (table_index); + + vl_api_send_msg (reg, (u8 *) rmp); +} + +static void vl_api_classify_trace_set_table_t_handler + (vl_api_classify_trace_set_table_t * mp) +{ + vnet_classify_main_t *cm = &vnet_classify_main; + vl_api_classify_trace_set_table_reply_t *rmp; + vl_api_registration_t *reg; + int rv = 0; + + reg = vl_api_client_index_to_registration (mp->client_index); + if (!reg) + return; + + u32 table_index = ntohl (mp->table_index); + if (table_index != ~0 && pool_is_free_index (cm->tables, table_index)) + { + rv = VNET_API_ERROR_INVALID_VALUE; + goto out; + } + + /* + * Maybe reorder tables such that masks are most-specific to least-specific. + */ + if (table_index != ~0 && mp->sort_masks) + table_index = classify_sort_table_chain (cm, table_index); + + classify_set_trace_chain (cm, table_index); + +out: + rmp = vl_msg_api_alloc (sizeof (*rmp)); + rmp->_vl_msg_id = ntohs ((VL_API_CLASSIFY_TRACE_SET_TABLE_REPLY)); + rmp->context = mp->context; + rmp->retval = ntohl (rv); + rmp->table_index = htonl (table_index); + + vl_api_send_msg (reg, (u8 *) rmp); +} + +static void vl_api_classify_trace_get_tables_t_handler + (vl_api_classify_trace_get_tables_t * mp) +{ + vnet_classify_main_t *cm = &vnet_classify_main; + vl_api_classify_trace_get_tables_reply_t *rmp; + vl_api_registration_t *reg; + int rv = 0; + u32 *tables = 0; + u32 count; + + reg = vl_api_client_index_to_registration (mp->client_index); + if (!reg) + return; + + u32 table_index = classify_get_trace_chain (); + if (table_index == ~0) + goto out; + + /* + * Form a vector of all classifier tables in this chain. + */ + vnet_classify_table_t *t; + u32 i; + + for (i = table_index; i != ~0; i = t->next_table_index) + { + vec_add1 (tables, i); + t = pool_elt_at_index (cm->tables, i); + } + +out: + count = vec_len (tables); + rmp = vl_msg_api_alloc_as_if_client (sizeof (*rmp) + count * sizeof (u32)); + rmp->_vl_msg_id = ntohs (VL_API_CLASSIFY_TRACE_GET_TABLES_REPLY); + rmp->context = mp->context; + rmp->retval = ntohl (rv); + rmp->count = htonl (count); + + for (i = 0; i < count; ++i) + { + rmp->indices[i] = htonl (tables[i]); + } + + vec_free (tables); + + vl_api_send_msg (reg, (u8 *) rmp); +} + static void vl_api_classify_add_del_table_t_handler (vl_api_classify_add_del_table_t * mp) @@ -86,6 +376,12 @@ static void vl_api_classify_add_del_table_t_handler foreach_classify_add_del_table_field; #undef _ + if (mask_len != match_n_vectors * sizeof (u32x4)) + { + rv = VNET_API_ERROR_INVALID_VALUE; + goto out; + } + /* The underlying API fails silently, on purpose, so check here */ if (mp->is_add == 0) /* delete */ { @@ -101,6 +397,9 @@ static void vl_api_classify_add_del_table_t_handler table_index = ~0; } + u8 current_data_flag = mp->current_data_flag; + i16 current_data_offset = clib_net_to_host_i16 (mp->current_data_offset); + rv = vnet_classify_add_del_table (cm, mp->mask, nbuckets, memory_size, skip_n_vectors, match_n_vectors, @@ -114,9 +413,9 @@ out: if (rv == 0 && mp->is_add) { t = pool_elt_at_index (cm->tables, table_index); - rmp->skip_n_vectors = ntohl(t->skip_n_vectors); - rmp->match_n_vectors = ntohl(t->match_n_vectors); - rmp->new_table_index = ntohl(table_index); + rmp->skip_n_vectors = htonl(t->skip_n_vectors); + rmp->match_n_vectors = htonl(t->match_n_vectors); + rmp->new_table_index = htonl(table_index); } else { @@ -134,9 +433,10 @@ static void vl_api_classify_add_del_session_t_handler vnet_classify_main_t *cm = &vnet_classify_main; vl_api_classify_add_del_session_reply_t *rmp; int rv; - u32 table_index, hit_next_index, opaque_index, metadata; + u32 table_index, hit_next_index, opaque_index, metadata, match_len; i32 advance; u8 action; + vnet_classify_table_t *t; table_index = ntohl (mp->table_index); hit_next_index = ntohl (mp->hit_next_index); @@ -144,11 +444,27 @@ static void vl_api_classify_add_del_session_t_handler advance = ntohl (mp->advance); action = mp->action; metadata = ntohl (mp->metadata); + match_len = ntohl (mp->match_len); + + if (pool_is_free_index (cm->tables, table_index)) + { + rv = VNET_API_ERROR_NO_SUCH_TABLE; + goto out; + } + + t = pool_elt_at_index (cm->tables, table_index); + + if (match_len != (t->skip_n_vectors + t->match_n_vectors) * sizeof (u32x4)) + { + rv = VNET_API_ERROR_INVALID_VALUE; + goto out; + } rv = vnet_classify_add_del_session (cm, table_index, mp->match, hit_next_index, opaque_index, advance, action, metadata, mp->is_add); +out: REPLY_MACRO (VL_API_CLASSIFY_ADD_DEL_SESSION_REPLY); } @@ -179,34 +495,44 @@ static void static void send_policer_classify_details (u32 sw_if_index, - u32 table_index, - unix_shared_memory_queue_t * q, u32 context) + u32 table_index, vl_api_registration_t * reg, + u32 context) { vl_api_policer_classify_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_POLICER_CLASSIFY_DETAILS); mp->context = context; mp->sw_if_index = htonl (sw_if_index); mp->table_index = htonl (table_index); - vl_msg_api_send_shmem (q, (u8 *) & mp); + vl_api_send_msg (reg, (u8 *) mp); } static void vl_api_policer_classify_dump_t_handler (vl_api_policer_classify_dump_t * mp) { - unix_shared_memory_queue_t *q; + vl_api_registration_t *reg; policer_classify_main_t *pcm = &policer_classify_main; u32 *vec_tbl; int i; + u32 filter_sw_if_index; - q = vl_api_client_index_to_input_queue (mp->client_index); - if (q == 0) + reg = vl_api_client_index_to_registration (mp->client_index); + if (!reg) return; - vec_tbl = pcm->classify_table_index_by_sw_if_index[mp->type]; + filter_sw_if_index = ntohl (mp->sw_if_index); + if (filter_sw_if_index + >= vec_len (pcm->classify_table_index_by_sw_if_index[mp->type])) + return; + + if (filter_sw_if_index != ~0) + vec_tbl = + &pcm->classify_table_index_by_sw_if_index[mp->type][filter_sw_if_index]; + else + vec_tbl = pcm->classify_table_index_by_sw_if_index[mp->type]; if (vec_len (vec_tbl)) { @@ -215,7 +541,7 @@ vl_api_policer_classify_dump_t_handler (vl_api_policer_classify_dump_t * mp) if (vec_elt (vec_tbl, i) == ~0) continue; - send_policer_classify_details (i, vec_elt (vec_tbl, i), q, + send_policer_classify_details (i, vec_elt (vec_tbl, i), reg, mp->context); } } @@ -224,10 +550,10 @@ vl_api_policer_classify_dump_t_handler (vl_api_policer_classify_dump_t * mp) static void vl_api_classify_table_ids_t_handler (vl_api_classify_table_ids_t * mp) { - unix_shared_memory_queue_t *q; + vl_api_registration_t *reg; - q = vl_api_client_index_to_input_queue (mp->client_index); - if (q == 0) + reg = vl_api_client_index_to_registration (mp->client_index); + if (!reg) return; vnet_classify_main_t *cm = &vnet_classify_main; @@ -236,10 +562,10 @@ vl_api_classify_table_ids_t_handler (vl_api_classify_table_ids_t * mp) u32 count; /* *INDENT-OFF* */ - pool_foreach (t, cm->tables, - ({ + pool_foreach (t, cm->tables) + { vec_add1 (table_ids, ntohl(t - cm->tables)); - })); + } /* *INDENT-ON* */ count = vec_len (table_ids); @@ -251,7 +577,7 @@ vl_api_classify_table_ids_t_handler (vl_api_classify_table_ids_t * mp) clib_memcpy (rmp->ids, table_ids, count * sizeof (u32)); rmp->retval = 0; - vl_msg_api_send_shmem (q, (u8 *) & rmp); + vl_api_send_msg (reg, (u8 *) rmp); vec_free (table_ids); } @@ -266,19 +592,21 @@ static void u32 sw_if_index = ntohl (mp->sw_if_index); u32 *acl = 0; - vec_validate (acl, INPUT_ACL_N_TABLES - 1); + vec_validate (acl, IN_OUT_ACL_N_TABLES - 1); vec_set (acl, ~0); VALIDATE_SW_IF_INDEX (mp); - input_acl_main_t *am = &input_acl_main; + in_out_acl_main_t *am = &in_out_acl_main; int if_idx; u32 type; - for (type = 0; type < INPUT_ACL_N_TABLES; type++) + for (type = 0; type < IN_OUT_ACL_N_TABLES; type++) { - u32 *vec_tbl = am->classify_table_index_by_sw_if_index[type]; + u32 *vec_tbl = + am->classify_table_index_by_sw_if_index[IN_OUT_ACL_INPUT_TABLE_GROUP] + [type]; if (vec_len (vec_tbl)) { for (if_idx = 0; if_idx < vec_len (vec_tbl); if_idx++) @@ -298,9 +626,9 @@ static void REPLY_MACRO2(VL_API_CLASSIFY_TABLE_BY_INTERFACE_REPLY, ({ rmp->sw_if_index = ntohl(sw_if_index); - rmp->l2_table_id = ntohl(acl[INPUT_ACL_TABLE_L2]); - rmp->ip4_table_id = ntohl(acl[INPUT_ACL_TABLE_IP4]); - rmp->ip6_table_id = ntohl(acl[INPUT_ACL_TABLE_IP6]); + rmp->l2_table_id = ntohl(acl[IN_OUT_ACL_TABLE_L2]); + rmp->ip4_table_id = ntohl(acl[IN_OUT_ACL_TABLE_IP4]); + rmp->ip6_table_id = ntohl(acl[IN_OUT_ACL_TABLE_IP6]); })); /* *INDENT-ON* */ vec_free (acl); @@ -309,10 +637,10 @@ static void static void vl_api_classify_table_info_t_handler (vl_api_classify_table_info_t * mp) { - unix_shared_memory_queue_t *q; + vl_api_registration_t *reg; - q = vl_api_client_index_to_input_queue (mp->client_index); - if (q == 0) + reg = vl_api_client_index_to_registration (mp->client_index); + if (!reg) return; vl_api_classify_table_info_reply_t *rmp = 0; @@ -322,8 +650,8 @@ vl_api_classify_table_info_t_handler (vl_api_classify_table_info_t * mp) vnet_classify_table_t *t; /* *INDENT-OFF* */ - pool_foreach (t, cm->tables, - ({ + pool_foreach (t, cm->tables) + { if (table_id == t - cm->tables) { rmp = vl_msg_api_alloc_as_if_client @@ -342,29 +670,22 @@ vl_api_classify_table_info_t_handler (vl_api_classify_table_info_t * mp) rmp->retval = 0; break; } - })); + } /* *INDENT-ON* */ if (rmp == 0) { rmp = vl_msg_api_alloc (sizeof (*rmp)); - rmp->_vl_msg_id = ntohs ((VL_API_CLASSIFY_TABLE_INFO_REPLY)); + rmp->_vl_msg_id = ntohs (VL_API_CLASSIFY_TABLE_INFO_REPLY); rmp->context = mp->context; rmp->retval = ntohl (VNET_API_ERROR_CLASSIFY_TABLE_NOT_FOUND); } - vl_msg_api_send_shmem (q, (u8 *) & rmp); + vl_api_send_msg (reg, (u8 *) rmp); } static void -vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t * - mp) -{ - clib_warning ("BUG"); -} - -static void -send_classify_session_details (unix_shared_memory_queue_t * q, +send_classify_session_details (vl_api_registration_t * reg, u32 table_id, u32 match_length, vnet_classify_entry_t * e, u32 context) @@ -372,7 +693,7 @@ send_classify_session_details (unix_shared_memory_queue_t * q, vl_api_classify_session_details_t *rmp; rmp = vl_msg_api_alloc (sizeof (*rmp)); - memset (rmp, 0, sizeof (*rmp)); + clib_memset (rmp, 0, sizeof (*rmp)); rmp->_vl_msg_id = ntohs (VL_API_CLASSIFY_SESSION_DETAILS); rmp->context = context; rmp->table_id = ntohl (table_id); @@ -382,25 +703,25 @@ send_classify_session_details (unix_shared_memory_queue_t * q, rmp->match_length = ntohl (match_length); clib_memcpy (rmp->match, e->key, match_length); - vl_msg_api_send_shmem (q, (u8 *) & rmp); + vl_api_send_msg (reg, (u8 *) rmp); } static void vl_api_classify_session_dump_t_handler (vl_api_classify_session_dump_t * mp) { vnet_classify_main_t *cm = &vnet_classify_main; - unix_shared_memory_queue_t *q; + vl_api_registration_t *reg; u32 table_id = ntohl (mp->table_id); vnet_classify_table_t *t; - q = vl_api_client_index_to_input_queue (mp->client_index); - if (!q) + reg = vl_api_client_index_to_registration (mp->client_index); + if (!reg) return; /* *INDENT-OFF* */ - pool_foreach (t, cm->tables, - ({ + pool_foreach (t, cm->tables) + { if (table_id == t - cm->tables) { vnet_classify_bucket_t * b; @@ -424,14 +745,14 @@ vl_api_classify_session_dump_t_handler (vl_api_classify_session_dump_t * mp) continue; send_classify_session_details - (q, table_id, t->match_n_vectors * sizeof (u32x4), + (reg, table_id, t->match_n_vectors * sizeof (u32x4), v, mp->context); } } } break; } - })); + } /* *INDENT-ON* */ } @@ -460,34 +781,44 @@ static void static void send_flow_classify_details (u32 sw_if_index, - u32 table_index, - unix_shared_memory_queue_t * q, u32 context) + u32 table_index, vl_api_registration_t * reg, + u32 context) { vl_api_flow_classify_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_FLOW_CLASSIFY_DETAILS); mp->context = context; mp->sw_if_index = htonl (sw_if_index); mp->table_index = htonl (table_index); - vl_msg_api_send_shmem (q, (u8 *) & mp); + vl_api_send_msg (reg, (u8 *) mp); } static void vl_api_flow_classify_dump_t_handler (vl_api_flow_classify_dump_t * mp) { - unix_shared_memory_queue_t *q; + vl_api_registration_t *reg; flow_classify_main_t *pcm = &flow_classify_main; u32 *vec_tbl; int i; + u32 filter_sw_if_index; - q = vl_api_client_index_to_input_queue (mp->client_index); - if (q == 0) + reg = vl_api_client_index_to_registration (mp->client_index); + if (!reg) return; - vec_tbl = pcm->classify_table_index_by_sw_if_index[mp->type]; + filter_sw_if_index = ntohl (mp->sw_if_index); + if (filter_sw_if_index + >= vec_len (pcm->classify_table_index_by_sw_if_index[mp->type])) + return; + + if (filter_sw_if_index != ~0) + vec_tbl = + &pcm->classify_table_index_by_sw_if_index[mp->type][filter_sw_if_index]; + else + vec_tbl = pcm->classify_table_index_by_sw_if_index[mp->type]; if (vec_len (vec_tbl)) { @@ -496,16 +827,126 @@ vl_api_flow_classify_dump_t_handler (vl_api_flow_classify_dump_t * mp) if (vec_elt (vec_tbl, i) == ~0) continue; - send_flow_classify_details (i, vec_elt (vec_tbl, i), q, + send_flow_classify_details (i, vec_elt (vec_tbl, i), reg, mp->context); } } } +static void vl_api_classify_set_interface_ip_table_t_handler + (vl_api_classify_set_interface_ip_table_t * mp) +{ + vlib_main_t *vm = vlib_get_main (); + vl_api_classify_set_interface_ip_table_reply_t *rmp; + int rv; + + VALIDATE_SW_IF_INDEX (mp); + + u32 table_index = ntohl (mp->table_index); + u32 sw_if_index = ntohl (mp->sw_if_index); + + if (mp->is_ipv6) + rv = vnet_set_ip6_classify_intfc (vm, sw_if_index, table_index); + else + rv = vnet_set_ip4_classify_intfc (vm, sw_if_index, table_index); + + BAD_SW_IF_INDEX_LABEL; + + REPLY_MACRO (VL_API_CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY); +} + +static void vl_api_classify_set_interface_l2_tables_t_handler + (vl_api_classify_set_interface_l2_tables_t * mp) +{ + vl_api_classify_set_interface_l2_tables_reply_t *rmp; + int rv; + u32 sw_if_index, ip4_table_index, ip6_table_index, other_table_index; + int enable; + + ip4_table_index = ntohl (mp->ip4_table_index); + ip6_table_index = ntohl (mp->ip6_table_index); + other_table_index = ntohl (mp->other_table_index); + sw_if_index = ntohl (mp->sw_if_index); + + VALIDATE_SW_IF_INDEX (mp); + + if (mp->is_input) + rv = vnet_l2_input_classify_set_tables (sw_if_index, ip4_table_index, + ip6_table_index, + other_table_index); + else + rv = vnet_l2_output_classify_set_tables (sw_if_index, ip4_table_index, + ip6_table_index, + other_table_index); + + if (rv == 0) + { + if (ip4_table_index != ~0 || ip6_table_index != ~0 + || other_table_index != ~0) + enable = 1; + else + enable = 0; + + if (mp->is_input) + vnet_l2_input_classify_enable_disable (sw_if_index, enable); + else + vnet_l2_output_classify_enable_disable (sw_if_index, enable); + } + + BAD_SW_IF_INDEX_LABEL; + + REPLY_MACRO (VL_API_CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY); +} + +static void vl_api_input_acl_set_interface_t_handler + (vl_api_input_acl_set_interface_t * mp) +{ + vlib_main_t *vm = vlib_get_main (); + vl_api_input_acl_set_interface_reply_t *rmp; + int rv; + + VALIDATE_SW_IF_INDEX (mp); + + u32 ip4_table_index = ntohl (mp->ip4_table_index); + u32 ip6_table_index = ntohl (mp->ip6_table_index); + u32 l2_table_index = ntohl (mp->l2_table_index); + u32 sw_if_index = ntohl (mp->sw_if_index); + + rv = vnet_set_input_acl_intfc (vm, sw_if_index, ip4_table_index, + ip6_table_index, l2_table_index, mp->is_add); + + BAD_SW_IF_INDEX_LABEL; + + REPLY_MACRO (VL_API_INPUT_ACL_SET_INTERFACE_REPLY); +} + +static void vl_api_output_acl_set_interface_t_handler + (vl_api_output_acl_set_interface_t * mp) +{ + vlib_main_t *vm = vlib_get_main (); + vl_api_output_acl_set_interface_reply_t *rmp; + int rv; + + VALIDATE_SW_IF_INDEX (mp); + + u32 ip4_table_index = ntohl (mp->ip4_table_index); + u32 ip6_table_index = ntohl (mp->ip6_table_index); + u32 l2_table_index = ntohl (mp->l2_table_index); + u32 sw_if_index = ntohl (mp->sw_if_index); + + rv = vnet_set_output_acl_intfc (vm, sw_if_index, ip4_table_index, + ip6_table_index, l2_table_index, + mp->is_add); + + BAD_SW_IF_INDEX_LABEL; + + REPLY_MACRO (VL_API_OUTPUT_ACL_SET_INTERFACE_REPLY); +} + /* * classify_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() */ @@ -524,7 +965,7 @@ setup_message_id_table (api_main_t * am) static clib_error_t * classify_api_hookup (vlib_main_t * vm) { - api_main_t *am = &api_main; + api_main_t *am = vlibapi_get_main (); #define _(N,n) \ vl_msg_api_set_handlers(VL_API_##N, #n, \