summaryrefslogtreecommitdiffstats
path: root/src/plugins/ioam/analyse
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/ioam/analyse')
-rw-r--r--src/plugins/ioam/analyse/ioam_analyse.h23
-rw-r--r--src/plugins/ioam/analyse/ip6/ip6_ioam_analyse.h59
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_ */
/*