diff options
Diffstat (limited to 'src/plugins/ioam/analyse')
-rw-r--r-- | src/plugins/ioam/analyse/ioam_analyse.h | 23 | ||||
-rw-r--r-- | src/plugins/ioam/analyse/ip6/ip6_ioam_analyse.h | 59 |
2 files changed, 77 insertions, 5 deletions
diff --git a/src/plugins/ioam/analyse/ioam_analyse.h b/src/plugins/ioam/analyse/ioam_analyse.h index d5b6fbe52a9..3c69d71f349 100644 --- a/src/plugins/ioam/analyse/ioam_analyse.h +++ b/src/plugins/ioam/analyse/ioam_analyse.h @@ -123,12 +123,14 @@ typedef struct ioam_analyser_data_t_ } ioam_analyser_data_t; always_inline f64 -ip6_ioam_analyse_calc_delay (ioam_trace_hdr_t * trace, u16 trace_len) +ip6_ioam_analyse_calc_delay (ioam_trace_hdr_t * trace, u16 trace_len, + u8 oneway) { u16 size_of_traceopt_per_node, size_of_all_traceopts; u8 num_nodes; - u32 *start_elt, *end_elt; + u32 *start_elt, *end_elt, *uturn_elt;; u32 start_time, end_time; + u8 done = 0; size_of_traceopt_per_node = fetch_trace_data_size (trace->ioam_trace_type); // Unknown trace type @@ -145,6 +147,19 @@ ip6_ioam_analyse_calc_delay (ioam_trace_hdr_t * trace, u16 trace_len) trace->elts + (u32) (size_of_traceopt_per_node * (num_nodes - 1) / sizeof (u32)); + if (oneway && (trace->ioam_trace_type & BIT_TTL_NODEID)) + { + done = 0; + do + { + uturn_elt = start_elt - size_of_traceopt_per_node / sizeof (u32); + + if ((clib_net_to_host_u32 (*start_elt) >> 24) <= + (clib_net_to_host_u32 (*uturn_elt) >> 24)) + done = 1; + } + while (!done && (start_elt = uturn_elt) != end_elt); + } if (trace->ioam_trace_type & BIT_TTL_NODEID) { start_elt++; @@ -155,7 +170,6 @@ ip6_ioam_analyse_calc_delay (ioam_trace_hdr_t * trace, u16 trace_len) start_elt++; end_elt++; } - start_time = clib_net_to_host_u32 (*start_elt); end_time = clib_net_to_host_u32 (*end_elt); @@ -273,11 +287,10 @@ ip6_ioam_analyse_hbh_trace (ioam_analyser_data_t * data, found_match: trace_record->pkt_counter++; trace_record->bytes_counter += pak_len; - if (trace->ioam_trace_type & BIT_TIMESTAMP) { /* Calculate time delay */ - u32 delay = (u32) ip6_ioam_analyse_calc_delay (trace, trace_len); + u32 delay = (u32) ip6_ioam_analyse_calc_delay (trace, trace_len, 0); if (delay < trace_record->min_delay) trace_record->min_delay = delay; else if (delay > trace_record->max_delay) diff --git a/src/plugins/ioam/analyse/ip6/ip6_ioam_analyse.h b/src/plugins/ioam/analyse/ip6/ip6_ioam_analyse.h index f6abdce3c9a..5a2a2d70028 100644 --- a/src/plugins/ioam/analyse/ip6/ip6_ioam_analyse.h +++ b/src/plugins/ioam/analyse/ip6/ip6_ioam_analyse.h @@ -18,6 +18,7 @@ #include <ioam/analyse/ioam_analyse.h> #include <vnet/ip/ip6_hop_by_hop.h> +#include <ioam/encap/ip6_ioam_trace.h> /** @brief IP6-iOAM analyser main structure. @note cache aligned. @@ -57,6 +58,64 @@ ioam_analyse_get_data_from_flow_id (u32 flow_id) return (ioam_analyser_main.aggregated_data + flow_id); } +always_inline void * +ip6_ioam_find_hbh_option (ip6_hop_by_hop_header_t * hbh0, u8 option) +{ + ip6_hop_by_hop_option_t *opt0, *limit0; + u8 type0; + + opt0 = (ip6_hop_by_hop_option_t *) (hbh0 + 1); + limit0 = + (ip6_hop_by_hop_option_t *) ((u8 *) hbh0 + ((hbh0->length + 1) << 3)); + + while (opt0 < limit0) + { + type0 = opt0->type; + if (type0 == option) + return ((void *) opt0); + + if (0 == type0) + { + opt0 = (ip6_hop_by_hop_option_t *) ((u8 *) opt0) + 1; + continue; + } + opt0 = (ip6_hop_by_hop_option_t *) + (((u8 *) opt0) + opt0->length + sizeof (ip6_hop_by_hop_option_t)); + } + + return NULL; +} + +always_inline int +ip6_ioam_analyse_compare_path_delay (ip6_hop_by_hop_header_t * hbh0, + ip6_hop_by_hop_header_t * hbh1, + bool oneway) +{ + ioam_trace_option_t *trace0 = NULL, *trace1 = NULL; + f64 delay0, delay1; + + trace0 = + ip6_ioam_find_hbh_option (hbh0, HBH_OPTION_TYPE_IOAM_TRACE_DATA_LIST); + trace1 = + ip6_ioam_find_hbh_option (hbh1, HBH_OPTION_TYPE_IOAM_TRACE_DATA_LIST); + + if (PREDICT_FALSE ((trace0 == NULL) && (trace1 == NULL))) + return 0; + + if (PREDICT_FALSE (trace1 == NULL)) + return 1; + + if (PREDICT_FALSE (trace0 == NULL)) + return -1; + + delay0 = ip6_ioam_analyse_calc_delay (&trace0->trace_hdr, + trace0->hdr.length - 2, oneway); + delay1 = ip6_ioam_analyse_calc_delay (&trace1->trace_hdr, + trace1->hdr.length - 2, oneway); + + return (delay0 - delay1); +} + #endif /* PLUGINS_IOAM_PLUGIN_IOAM_ANALYSE_IP6_IOAM_ANALYSE_NODE_H_ */ /* |