summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--vnet/vnet/ip/ip6_hop_by_hop.c13
-rw-r--r--vnet/vnet/ip/ip6_hop_by_hop.h3
-rw-r--r--vpp-api-test/vat/api_format.c133
-rw-r--r--vpp/api/api.c63
-rw-r--r--vpp/api/vpe.api80
5 files changed, 283 insertions, 9 deletions
diff --git a/vnet/vnet/ip/ip6_hop_by_hop.c b/vnet/vnet/ip/ip6_hop_by_hop.c
index 339cbc30c48..74f79506007 100644
--- a/vnet/vnet/ip/ip6_hop_by_hop.c
+++ b/vnet/vnet/ip/ip6_hop_by_hop.c
@@ -1080,7 +1080,7 @@ int ip6_ioam_set_rewrite (u8 **rwp, u32 trace_type, u32 trace_option_elts,
}
clib_error_t *
-clear_ioam_rewrite_fn()
+clear_ioam_rewrite_fn(void)
{
ip6_hop_by_hop_main_t *hm = &ip6_hop_by_hop_main;
@@ -1096,11 +1096,18 @@ clear_ioam_rewrite_fn()
return 0;
}
+
+clib_error_t * clear_ioam_rewrite_command_fn (vlib_main_t * vm,
+ unformat_input_t * input,
+ vlib_cli_command_t * cmd)
+{
+ return(clear_ioam_rewrite_fn());
+}
VLIB_CLI_COMMAND (ip6_clear_ioam_trace_cmd, static) = {
.path = "clear ioam rewrite",
.short_help = "clear ioam rewrite",
- .function = clear_ioam_rewrite_fn,
+ .function = clear_ioam_rewrite_command_fn,
};
clib_error_t *
@@ -1126,7 +1133,7 @@ ip6_ioam_trace_profile_set(u32 trace_option_elts, u32 trace_type, u32 node_id,
break;
default:
- return clib_error_return (0, "ip6_ioam_set_rewrite returned %d", rv);
+ return clib_error_return_code(0, rv, 0, "ip6_ioam_set_rewrite returned %d", rv);
}
return 0;
diff --git a/vnet/vnet/ip/ip6_hop_by_hop.h b/vnet/vnet/ip/ip6_hop_by_hop.h
index fc98ae2f668..2ec83f2be35 100644
--- a/vnet/vnet/ip/ip6_hop_by_hop.h
+++ b/vnet/vnet/ip/ip6_hop_by_hop.h
@@ -73,8 +73,7 @@ ip6_ioam_trace_profile_set(u32 trace_option_elts, u32 trace_type, u32 node_id,
extern int ip6_ioam_set_destination (ip6_address_t *addr, u32 mask_width,
u32 vrf_id, int is_add, int is_pop, int is_none);
-
-extern clib_error_t * clear_ioam_trace_fn();
+extern clib_error_t * clear_ioam_rewrite_fn(void);
static inline u8 is_zero_ip4_address (ip4_address_t *a)
{
diff --git a/vpp-api-test/vat/api_format.c b/vpp-api-test/vat/api_format.c
index 50153fe3202..180e76e1b11 100644
--- a/vpp-api-test/vat/api_format.c
+++ b/vpp-api-test/vat/api_format.c
@@ -41,6 +41,7 @@
#endif
#include <vnet/map/map.h>
#include <vnet/cop/cop.h>
+#include <vnet/ip/ip6_hop_by_hop.h>
#include "vat/json_format.h"
@@ -1897,7 +1898,10 @@ _(want_interface_events_reply) \
_(want_stats_reply) \
_(cop_interface_enable_disable_reply) \
_(cop_whitelist_enable_disable_reply) \
-_(sw_interface_clear_stats_reply)
+_(sw_interface_clear_stats_reply) \
+_(trace_profile_add_reply) \
+_(trace_profile_apply_reply) \
+_(trace_profile_del_reply)
#define _(n) \
static void vl_api_##n##_t_handler \
@@ -2051,7 +2055,10 @@ _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply) \
_(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
_(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
_(GET_NODE_GRAPH_REPLY, get_node_graph_reply) \
-_(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)
+_(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply) \
+_(TRACE_PROFILE_ADD_REPLY, trace_profile_add_reply) \
+_(TRACE_PROFILE_APPLY_REPLY, trace_profile_apply_reply) \
+_(TRACE_PROFILE_DEL_REPLY, trace_profile_del_reply)
/* M: construct, but don't yet send a message */
@@ -5092,7 +5099,121 @@ static int api_l2_patch_add_del (vat_main_t * vam)
/* NOTREACHED */
return 0;
}
+static int api_trace_profile_add (vat_main_t *vam)
+{
+ unformat_input_t * input = vam->input;
+ vl_api_trace_profile_add_t *mp;
+ f64 timeout;
+ u32 id = 0;
+ u32 trace_option_elts = 0;
+ u32 trace_type = 0, node_id = 0, app_data = 0, trace_tsp = 2;
+ int has_pow_option = 0;
+ int has_ppc_option = 0;
+
+ while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
+ {
+ if (unformat (input, "id %d trace-type 0x%x trace-elts %d "
+ "trace-tsp %d node-id 0x%x app-data 0x%x",
+ &id, &trace_type, &trace_option_elts, &trace_tsp,
+ &node_id, &app_data))
+ ;
+ else if (unformat (input, "pow"))
+ has_pow_option = 1;
+ else if (unformat (input, "ppc encap"))
+ has_ppc_option = PPC_ENCAP;
+ else if (unformat (input, "ppc decap"))
+ has_ppc_option = PPC_DECAP;
+ else if (unformat (input, "ppc none"))
+ has_ppc_option = PPC_NONE;
+ else
+ break;
+ }
+ M(TRACE_PROFILE_ADD, trace_profile_add);
+ mp->id = htons(id);
+ mp->trace_type = trace_type;
+ mp->trace_num_elt = trace_option_elts;
+ mp->trace_ppc = has_ppc_option;
+ mp->trace_app_data = htonl(app_data);
+ mp->pow_enable = has_pow_option;
+ mp->trace_tsp = trace_tsp;
+ mp->node_id = htonl(node_id);
+
+ S; W;
+
+ return(0);
+
+}
+static int api_trace_profile_apply (vat_main_t *vam)
+{
+ unformat_input_t * input = vam->input;
+ vl_api_trace_profile_apply_t *mp;
+ f64 timeout;
+ ip6_address_t addr;
+ u32 mask_width = ~0;
+ int is_add = 0;
+ int is_pop = 0;
+ int is_none = 0;
+ u32 vrf_id = 0;
+ u32 id = 0;
+
+ while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
+ {
+ if (unformat (input, "%U/%d",
+ unformat_ip6_address, &addr, &mask_width))
+ ;
+ else if (unformat (input, "id %d", &id))
+ ;
+ else if (unformat (input, "vrf-id %d", &vrf_id))
+ ;
+ else if (unformat (input, "add"))
+ is_add = 1;
+ else if (unformat (input, "pop"))
+ is_pop = 1;
+ else if (unformat (input, "none"))
+ is_none = 1;
+ else
+ break;
+ }
+
+ if ((is_add + is_pop + is_none) != 1) {
+ errmsg("One of (add, pop, none) required");
+ return -99;
+ }
+ if (mask_width == ~0) {
+ errmsg("<address>/<mask-width> required");
+ return -99;
+ }
+ M(TRACE_PROFILE_APPLY, trace_profile_apply);
+ memcpy(mp->dest_ipv6, &addr, sizeof(mp->dest_ipv6));
+ mp->id = htons(id);
+ mp->prefix_length = htonl(mask_width);
+ mp->vrf_id = htonl(vrf_id);
+ if (is_add)
+ mp->trace_op = IOAM_HBYH_ADD;
+ else if (is_pop)
+ mp->trace_op = IOAM_HBYH_POP;
+ else
+ mp->trace_op = IOAM_HBYH_MOD;
+
+ if(is_none)
+ mp->enable = 0;
+ else
+ mp->enable = 1;
+
+ S; W;
+ return 0;
+}
+
+static int api_trace_profile_del (vat_main_t *vam)
+{
+ vl_api_trace_profile_del_t *mp;
+ f64 timeout;
+
+ M(TRACE_PROFILE_DEL, trace_profile_del);
+ S; W;
+ return 0;
+}
static int api_sr_tunnel_add_del (vat_main_t * vam)
{
unformat_input_t * i = vam->input;
@@ -9100,7 +9221,13 @@ _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
_(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n" \
"fib-id <nn> [ip4][ip6][default]") \
_(get_node_graph, " ") \
-_(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")
+_(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>") \
+_(trace_profile_add, "id <nn> trace-type <0x1f|0x3|0x9|0x11|0x19> " \
+ "trace-elts <nn> trace-tsp <0|1|2|3> node-id <node id in hex> " \
+ "app-data <app_data in hex> [pow] [ppc <encap|decap>]") \
+_(trace_profile_apply, "id <nn> <ip6-address>/<width>" \
+ " vrf_id <nn> add | pop | none") \
+_(trace_profile_del, "")
/* List of command functions, CLI names map directly to functions */
#define foreach_cli_function \
diff --git a/vpp/api/api.c b/vpp/api/api.c
index 40cfa27bb11..aae8a19d244 100644
--- a/vpp/api/api.c
+++ b/vpp/api/api.c
@@ -70,6 +70,7 @@
#include <vnet/lisp-gpe/lisp_gpe.h>
#include <vnet/map/map.h>
#include <vnet/cop/cop.h>
+#include <vnet/ip/ip6_hop_by_hop.h>
#undef BIHASH_TYPE
#undef __included_bihash_template_h__
@@ -312,7 +313,10 @@ _(MAP_SUMMARY_STATS, map_summary_stats) \
_(COP_INTERFACE_ENABLE_DISABLE, cop_interface_enable_disable) \
_(COP_WHITELIST_ENABLE_DISABLE, cop_whitelist_enable_disable) \
_(GET_NODE_GRAPH, get_node_graph) \
-_(SW_INTERFACE_CLEAR_STATS, sw_interface_clear_stats)
+_(SW_INTERFACE_CLEAR_STATS, sw_interface_clear_stats) \
+_(TRACE_PROFILE_ADD, trace_profile_add) \
+_(TRACE_PROFILE_APPLY, trace_profile_apply) \
+_(TRACE_PROFILE_DEL, trace_profile_del)
#define QUOTE_(x) #x
#define QUOTE(x) QUOTE_(x)
@@ -4997,6 +5001,63 @@ static void vl_api_get_node_graph_t_handler
rmp->reply_in_shmem = (uword) vector);
}
+static void vl_api_trace_profile_add_t_handler
+(vl_api_trace_profile_add_t *mp)
+{
+ int rv = 0;
+ vl_api_trace_profile_add_reply_t * rmp;
+ clib_error_t *error;
+
+ /* Ignoring the profile id as currently a single profile
+ * is supported */
+ error = ip6_ioam_trace_profile_set(mp->trace_num_elt, mp->trace_type,
+ ntohl(mp->node_id), ntohl(mp->trace_app_data),
+ mp->pow_enable, mp->trace_tsp,
+ mp->trace_ppc);
+ if (error) {
+ clib_error_report(error);
+ rv = clib_error_get_code(error);
+ }
+
+ REPLY_MACRO(VL_API_TRACE_PROFILE_ADD_REPLY);
+}
+
+static void vl_api_trace_profile_apply_t_handler
+(vl_api_trace_profile_apply_t *mp)
+{
+ int rv = 0;
+ vl_api_trace_profile_apply_reply_t * rmp;
+
+ if (mp->enable != 0) {
+ rv = ip6_ioam_set_destination ((ip6_address_t *)(&mp->dest_ipv6),
+ ntohl(mp->prefix_length),
+ ntohl(mp->vrf_id),
+ mp->trace_op == IOAM_HBYH_ADD,
+ mp->trace_op == IOAM_HBYH_POP,
+ mp->trace_op == IOAM_HBYH_MOD);
+ } else {
+ //ip6_ioam_clear_destination(&ip6, mp->prefix_length, mp->vrf_id);
+ }
+ REPLY_MACRO(VL_API_TRACE_PROFILE_APPLY_REPLY);
+}
+
+static void vl_api_trace_profile_del_t_handler
+(vl_api_trace_profile_del_t *mp)
+{
+ int rv = 0;
+ vl_api_trace_profile_del_reply_t * rmp;
+ clib_error_t *error;
+
+ error = clear_ioam_rewrite_fn();
+ if (error) {
+ clib_error_report(error);
+ rv = clib_error_get_code(error);
+ }
+
+ REPLY_MACRO(VL_API_TRACE_PROFILE_DEL_REPLY);
+}
+
+
#define BOUNCE_HANDLER(nn) \
static void vl_api_##nn##_t_handler ( \
vl_api_##nn##_t *mp) \
diff --git a/vpp/api/vpe.api b/vpp/api/vpe.api
index 29cd1badcbc..dd20a0b81da 100644
--- a/vpp/api/vpe.api
+++ b/vpp/api/vpe.api
@@ -2862,3 +2862,83 @@ define sw_interface_clear_stats_reply {
u32 context;
i32 retval;
};
+
+/** \brief IOAM Trace : Set TRACE profile
+ @param id - profile id
+ @param trace_type - Trace type
+ @param trace_num_elt - Number of nodes in trace path
+ @param trace_ppc - Trace PPC (none/encap/decap)
+ @param trace_tsp - Trace timestamp precision (0-sec,1-ms,2-us,3-ns)
+ @param trace_app_data - Trace application data, can be any 4 bytes
+ @param pow_enable - Proof of Work enabled or not flag
+ @param node_id - Id of this node
+*/
+define trace_profile_add {
+ u32 client_index;
+ u32 context;
+ u16 id;
+ u8 trace_type;
+ u8 trace_num_elt;
+ u8 trace_ppc;
+ u8 trace_tsp;
+ u32 trace_app_data;
+ u8 pow_enable;
+ u32 node_id;
+};
+
+/** \brief Trace profile add / del response
+ @param context - sender context, to match reply w/ request
+ @param retval - return value for request
+*/
+define trace_profile_add_reply {
+ u32 context;
+ i32 retval;
+};
+
+/** \brief IOAM Trace enable trace profile for a flow
+ @param id - id of the trace profile to be applied
+ @param dest_ipv6 - Destination IPv6 address
+ @param prefix_length - prefix mask
+ @param vrf_id - VRF ID
+ @param trace_op - Trace operation (add/mod/del)
+ @param enable - apply/remove the trace profile for the flow
+*/
+define trace_profile_apply {
+ u32 client_index;
+ u32 context;
+ u16 id;
+ u8 dest_ipv6[16];
+ u32 prefix_length;
+ u32 vrf_id;
+ u8 trace_op;
+ u8 enable;
+};
+
+/** \brief Trace profile apply response
+ @param context - sender context, to match reply w/ request
+ @param retval - return value for request
+*/
+define trace_profile_apply_reply {
+ u32 context;
+ i32 retval;
+};
+
+/** \brief Delete Trace Profile
+ @param client_index - opaque cookie to identify the sender
+ @param context - sender context, to match reply w/ request
+ @param index - MAP Domain index
+*/
+define trace_profile_del {
+ u32 client_index;
+ u32 context;
+ u16 id;
+};
+
+/** \brief Trace profile add / del response
+ @param context - sender context, to match reply w/ request
+ @param retval - return value for request
+*/
+define trace_profile_del_reply {
+ u32 context;
+ i32 retval;
+};