diff options
-rw-r--r-- | vnet/vnet/ip/ip6_hop_by_hop.c | 13 | ||||
-rw-r--r-- | vnet/vnet/ip/ip6_hop_by_hop.h | 3 | ||||
-rw-r--r-- | vpp-api-test/vat/api_format.c | 133 | ||||
-rw-r--r-- | vpp/api/api.c | 63 | ||||
-rw-r--r-- | vpp/api/vpe.api | 80 |
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; +}; |