#include <vnet/ipsec-gre/ipsec_gre.h>
#include <vnet/flow/flow_report_classify.h>
#include <vnet/ip/punt.h>
+#include <vnet/feature/feature.h>
#undef BIHASH_TYPE
#undef __included_bihash_template_h__
#include <vnet/l2/l2_fib.h>
#include <vnet/l2/l2_bd.h>
#include <vpp-api/vpe_msg_enum.h>
+#include <vnet/span/span.h>
#include <vnet/fib/ip6_fib.h>
#include <vnet/fib/ip4_fib.h>
_(IPFIX_CLASSIFY_STREAM_DUMP, ipfix_classify_stream_dump) \
_(IPFIX_CLASSIFY_TABLE_ADD_DEL, ipfix_classify_table_add_del) \
_(IPFIX_CLASSIFY_TABLE_DUMP, ipfix_classify_table_dump) \
+_(SW_INTERFACE_SPAN_ENABLE_DISABLE, sw_interface_span_enable_disable) \
+_(SW_INTERFACE_SPAN_DUMP, sw_interface_span_dump) \
_(GET_NEXT_INDEX, get_next_index) \
_(PG_CREATE_INTERFACE, pg_create_interface) \
_(PG_CAPTURE, pg_capture) \
_(IP_FIB_DUMP, ip_fib_dump) \
_(IP_FIB_DETAILS, ip_fib_details) \
_(IP6_FIB_DUMP, ip6_fib_dump) \
-_(IP6_FIB_DETAILS, ip6_fib_details)
+_(IP6_FIB_DETAILS, ip6_fib_details) \
+_(FEATURE_ENABLE_DISABLE, feature_enable_disable)
#define QUOTE_(x) #x
#define QUOTE(x) QUOTE_(x)
_(skip_n_vectors) \
_(match_n_vectors) \
_(next_table_index) \
-_(miss_next_index)
+_(miss_next_index) \
+_(current_data_flag) \
+_(current_data_offset)
static void vl_api_classify_add_del_table_t_handler
(vl_api_classify_add_del_table_t * mp)
#undef _
/* The underlying API fails silently, on purpose, so check here */
- if (mp->is_add == 0)
- if (pool_is_free_index (cm->tables, table_index))
- {
- rv = VNET_API_ERROR_NO_SUCH_TABLE;
- goto out;
- }
+ if (mp->is_add == 0) /* delete */
+ {
+ if (pool_is_free_index (cm->tables, table_index))
+ {
+ rv = VNET_API_ERROR_NO_SUCH_TABLE;
+ goto out;
+ }
+ }
+ else /* add or update */
+ {
+ if (table_index != ~0 && pool_is_free_index (cm->tables, table_index))
+ table_index = ~0;
+ }
rv = vnet_classify_add_del_table
(cm, mp->mask, nbuckets, memory_size,
skip_n_vectors, match_n_vectors,
- next_table_index, miss_next_index, &table_index, mp->is_add);
+ next_table_index, miss_next_index, &table_index,
+ current_data_flag, current_data_offset, mp->is_add);
out:
/* *INDENT-OFF* */
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;
+ u32 table_index, hit_next_index, opaque_index, metadata;
i32 advance;
+ u8 action;
table_index = ntohl (mp->table_index);
hit_next_index = ntohl (mp->hit_next_index);
opaque_index = ntohl (mp->opaque_index);
advance = ntohl (mp->advance);
+ action = mp->action;
+ metadata = ntohl (mp->metadata);
rv = vnet_classify_add_del_session
(cm, table_index, mp->match, hit_next_index, opaque_index,
- advance, mp->is_add);
+ advance, action, metadata, mp->is_add);
REPLY_MACRO (VL_API_CLASSIFY_ADD_DEL_SESSION_REPLY);
}
clib_warning ("BUG");
}
+
+static void
+copy_fib_next_hop (fib_route_path_encode_t * api_rpath,
+ vl_api_fib_path_t * fp)
+{
+ int is_ip4;
+
+ if (api_rpath->rpath.frp_proto == FIB_PROTOCOL_IP4)
+ fp->afi = IP46_TYPE_IP4;
+ else if (api_rpath->rpath.frp_proto == FIB_PROTOCOL_IP6)
+ fp->afi = IP46_TYPE_IP6;
+ else
+ {
+ is_ip4 = ip46_address_is_ip4 (&api_rpath->rpath.frp_addr);
+ if (is_ip4)
+ fp->afi = IP46_TYPE_IP4;
+ else
+ fp->afi = IP46_TYPE_IP6;
+ }
+ if (fp->afi == IP46_TYPE_IP4)
+ memcpy (fp->next_hop, &api_rpath->rpath.frp_addr.ip4,
+ sizeof (api_rpath->rpath.frp_addr.ip4));
+ else
+ memcpy (fp->next_hop, &api_rpath->rpath.frp_addr.ip6,
+ sizeof (api_rpath->rpath.frp_addr.ip6));
+}
+
static void
send_mpls_fib_details (vpe_api_main_t * am,
unix_shared_memory_queue_t * q,
vl_api_mpls_fib_details_t *mp;
fib_route_path_encode_t *api_rpath;
vl_api_fib_path_t *fp;
- int is_ip4, path_count;
+ int path_count;
path_count = vec_len (api_rpaths);
mp = vl_msg_api_alloc (sizeof (*mp) + path_count * sizeof (*fp));
memset (fp, 0, sizeof (*fp));
fp->weight = htonl (api_rpath->rpath.frp_weight);
fp->sw_if_index = htonl (api_rpath->rpath.frp_sw_if_index);
- memcpy (fp->next_hop, &api_rpath->rpath.frp_addr, sizeof (fp->next_hop));
- if (api_rpath->rpath.frp_proto == FIB_PROTOCOL_IP4)
- fp->afi = IP46_TYPE_IP4;
- else if (api_rpath->rpath.frp_proto == FIB_PROTOCOL_IP6)
- fp->afi = IP46_TYPE_IP6;
- else
- {
- is_ip4 = ip46_address_is_ip4 (&api_rpath->rpath.frp_addr);
- if (is_ip4)
- fp->afi = IP46_TYPE_IP4;
- else
- fp->afi = IP46_TYPE_IP6;
- }
+ copy_fib_next_hop (api_rpath, fp);
fp++;
}
vl_api_ip_fib_details_t *mp;
fib_route_path_encode_t *api_rpath;
vl_api_fib_path_t *fp;
- int is_ip4, path_count;
+ int path_count;
path_count = vec_len(api_rpaths);
mp = vl_msg_api_alloc (sizeof (*mp) + path_count * sizeof (*fp));
}
fp->weight = htonl(api_rpath->rpath.frp_weight);
fp->sw_if_index = htonl(api_rpath->rpath.frp_sw_if_index);
- memcpy(fp->next_hop, &api_rpath->rpath.frp_addr, sizeof(fp->next_hop));
- if (api_rpath->rpath.frp_proto == FIB_PROTOCOL_IP4)
- fp->afi = IP46_TYPE_IP4;
- else if (api_rpath->rpath.frp_proto == FIB_PROTOCOL_IP6)
- fp->afi = IP46_TYPE_IP6;
- else
- {
- is_ip4 = ip46_address_is_ip4 (&api_rpath->rpath.frp_addr);
- if (is_ip4)
- fp->afi = IP46_TYPE_IP4;
- else
- fp->afi = IP46_TYPE_IP6;
- }
+ copy_fib_next_hop (api_rpath, fp);
fp++;
}
vl_api_ip6_fib_details_t *mp;
fib_route_path_encode_t *api_rpath;
vl_api_fib_path_t *fp;
- int is_ip4, path_count;
+ int path_count;
path_count = vec_len(api_rpaths);
mp = vl_msg_api_alloc (sizeof (*mp) + path_count * sizeof (*fp));
}
fp->weight = htonl(api_rpath->rpath.frp_weight);
fp->sw_if_index = htonl(api_rpath->rpath.frp_sw_if_index);
- memcpy(fp->next_hop, &api_rpath->rpath.frp_addr, sizeof(fp->next_hop));
- if (api_rpath->rpath.frp_proto == FIB_PROTOCOL_IP4)
- fp->afi = IP46_TYPE_IP4;
- else if (api_rpath->rpath.frp_proto == FIB_PROTOCOL_IP6)
- fp->afi = IP46_TYPE_IP6;
- else
- {
- is_ip4 = ip46_address_is_ip4 (&api_rpath->rpath.frp_addr);
- if (is_ip4)
- fp->afi = IP46_TYPE_IP4;
- else
- fp->afi = IP46_TYPE_IP6;
- }
+ copy_fib_next_hop (api_rpath, fp);
fp++;
}
send_ipfix_classify_table_details (i, q, mp->context);
}
+static void
+ vl_api_sw_interface_span_enable_disable_t_handler
+ (vl_api_sw_interface_span_enable_disable_t * mp)
+{
+ vl_api_sw_interface_span_enable_disable_reply_t *rmp;
+ int rv;
+
+ vlib_main_t *vm = vlib_get_main ();
+
+ rv = span_add_delete_entry (vm, ntohl (mp->sw_if_index_from),
+ ntohl (mp->sw_if_index_to), mp->enable);
+
+ REPLY_MACRO (VL_API_SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY);
+}
+
+static void
+vl_api_sw_interface_span_dump_t_handler (vl_api_sw_interface_span_dump_t * mp)
+{
+
+ unix_shared_memory_queue_t *q;
+ vl_api_sw_interface_span_details_t *rmp;
+ span_main_t *sm = &span_main;
+ u32 src_sw_if_index = 0, *dst_sw_if_index;
+
+ q = vl_api_client_index_to_input_queue (mp->client_index);
+ vec_foreach (dst_sw_if_index, sm->dst_by_src_sw_if_index)
+ {
+ if (*dst_sw_if_index > 0)
+ {
+ rmp = vl_msg_api_alloc (sizeof (*rmp));
+ memset (rmp, 0, sizeof (*rmp));
+ rmp->_vl_msg_id = ntohs (VL_API_SW_INTERFACE_SPAN_DETAILS);
+ rmp->context = mp->context;
+
+ rmp->sw_if_index_from = htonl (src_sw_if_index);
+ rmp->sw_if_index_to = htonl (*dst_sw_if_index);
+
+ vl_msg_api_send_shmem (q, (u8 *) & rmp);
+ }
+ src_sw_if_index++;
+ }
+}
+
static void
vl_api_pg_create_interface_t_handler (vl_api_pg_create_interface_t * mp)
{
#endif
}
+static void
+vl_api_feature_enable_disable_t_handler (vl_api_feature_enable_disable_t * mp)
+{
+ vl_api_feature_enable_disable_reply_t *rmp;
+ int rv = 0;
+
+ u8 *arc_name = format (0, "%s%c", mp->arc_name, 0);
+ u8 *feature_name = format (0, "%s%c", mp->feature_name, 0);
+ u32 sw_if_index = ntohl (mp->sw_if_index);
+
+ vnet_feature_registration_t *reg;
+ reg =
+ vnet_get_feature_reg ((const char *) arc_name,
+ (const char *) feature_name);
+ if (reg == 0)
+ rv = VNET_API_ERROR_INVALID_VALUE;
+ else
+ {
+ clib_error_t *error = 0;
+
+ if (reg->enable_disable_cb)
+ error = reg->enable_disable_cb (sw_if_index, mp->enable);
+ if (!error)
+ vnet_feature_enable_disable ((const char *) arc_name,
+ (const char *) feature_name,
+ sw_if_index, mp->enable, 0, 0);
+ else
+ {
+ clib_error_report (error);
+ rv = VNET_API_ERROR_CANNOT_ENABLE_DISABLE_FEATURE;
+ }
+ }
+
+ vec_free (feature_name);
+ vec_free (arc_name);
+
+ REPLY_MACRO (VL_API_FEATURE_ENABLE_DISABLE_REPLY);
+}
+
#define BOUNCE_HANDLER(nn) \
static void vl_api_##nn##_t_handler ( \
vl_api_##nn##_t *mp) \