From fdd81af6afe6c782ad2c1a139210378badec626b Mon Sep 17 00:00:00 2001 From: AkshayaNadahalli Date: Thu, 1 Dec 2016 16:33:51 +0530 Subject: VPP-632 : InBand OAM Analyser Refer to jira ticket for more details. Change-Id: I6facb9ef8553a21464f9a2e612706f152badbb68 Signed-off-by: AkshayaNadahalli --- src/plugins/ioam/lib-e2e/e2e_util.h | 37 ++++++ src/plugins/ioam/lib-e2e/ioam_seqno_lib.c | 84 +++++++++++++ src/plugins/ioam/lib-e2e/ioam_seqno_lib.h | 201 ++++++++++++++++++++++++++++++ 3 files changed, 322 insertions(+) create mode 100644 src/plugins/ioam/lib-e2e/e2e_util.h create mode 100644 src/plugins/ioam/lib-e2e/ioam_seqno_lib.c create mode 100644 src/plugins/ioam/lib-e2e/ioam_seqno_lib.h (limited to 'src/plugins/ioam/lib-e2e') diff --git a/src/plugins/ioam/lib-e2e/e2e_util.h b/src/plugins/ioam/lib-e2e/e2e_util.h new file mode 100644 index 00000000000..f8a4ebd4797 --- /dev/null +++ b/src/plugins/ioam/lib-e2e/e2e_util.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2017 Cisco and/or its affiliates. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef PLUGINS_IOAM_PLUGIN_IOAM_LIB_E2E_E2E_UTIL_H_ +#define PLUGINS_IOAM_PLUGIN_IOAM_LIB_E2E_E2E_UTIL_H_ + +#include + +/* *INDENT-OFF* */ +typedef CLIB_PACKED(struct { + u8 e2e_type; + u8 reserved; + u32 e2e_data; +}) ioam_e2e_packet_t; +/* *INDENT-ON* */ + +#endif /* PLUGINS_IOAM_PLUGIN_IOAM_LIB_E2E_E2E_UTIL_H_ */ + +/* + * fd.io coding-style-patch-verification: ON + * + * Local Variables: + * eval: (c-set-style "gnu") + * End: + */ diff --git a/src/plugins/ioam/lib-e2e/ioam_seqno_lib.c b/src/plugins/ioam/lib-e2e/ioam_seqno_lib.c new file mode 100644 index 00000000000..bf78c1e3d2d --- /dev/null +++ b/src/plugins/ioam/lib-e2e/ioam_seqno_lib.c @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2017 Cisco and/or its affiliates. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include + +u8 * +show_ioam_seqno_cmd_fn (u8 * s, ioam_seqno_data * seqno_data, u8 enc) +{ + seqno_rx_info *rx; + + s = format (s, "SeqNo Data:\n"); + if (enc) + { + s = format (s, " Current Seq. Number : %llu\n", seqno_data->seq_num); + } + else + { + rx = &seqno_data->seqno_rx; + s = show_ioam_seqno_analyse_data_fn (s, rx); + } + + format (s, "\n"); + return s; +} + +u8 * +show_ioam_seqno_analyse_data_fn (u8 * s, seqno_rx_info * rx) +{ + s = format (s, " Highest Seq. Number : %llu\n", rx->bitmap.highest); + s = format (s, " Packets received : %llu\n", rx->rx_packets); + s = format (s, " Lost packets : %llu\n", rx->lost_packets); + s = format (s, " Reordered packets : %llu\n", rx->reordered_packets); + s = format (s, " Duplicate packets : %llu\n", rx->dup_packets); + + format (s, "\n"); + return s; +} + +void +ioam_seqno_init_data (ioam_seqno_data * data) +{ + data->seq_num = 0; + ioam_seqno_init_rx_info (&data->seqno_rx); + return; +} + +void +ioam_seqno_init_rx_info (seqno_rx_info * data) +{ + seqno_bitmap *bitmap = &data->bitmap; + bitmap->window_size = SEQNO_WINDOW_SIZE; + bitmap->array_size = SEQNO_WINDOW_ARRAY_SIZE; + bitmap->mask = 32 * SEQNO_WINDOW_ARRAY_SIZE - 1; + bitmap->array[0] = 0x00000000; /* pretend we haven seen sequence numbers 0 */ + bitmap->highest = 0; + + data->dup_packets = 0; + data->lost_packets = 0; + data->reordered_packets = 0; + data->rx_packets = 0; + return; +} + +/* + * fd.io coding-style-patch-verification: ON + * + * Local Variables: + * eval: (c-set-style "gnu") + * End: + */ diff --git a/src/plugins/ioam/lib-e2e/ioam_seqno_lib.h b/src/plugins/ioam/lib-e2e/ioam_seqno_lib.h new file mode 100644 index 00000000000..6bd38ff2968 --- /dev/null +++ b/src/plugins/ioam/lib-e2e/ioam_seqno_lib.h @@ -0,0 +1,201 @@ +/* + * Copyright (c) 2016 Cisco and/or its affiliates. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef PLUGINS_IOAM_PLUGIN_IOAM_LIB_E2E_IOAM_SEQNO_LIB_H_ +#define PLUGINS_IOAM_PLUGIN_IOAM_LIB_E2E_IOAM_SEQNO_LIB_H_ + +#include + +#define SEQ_CHECK_VALUE 0x80000000 /* for seq number wraparound detection */ + +#define SEQNO_WINDOW_SIZE 2048 +#define SEQNO_WINDOW_ARRAY_SIZE 64 + +typedef struct seqno_bitmap_ +{ + u32 window_size; + u32 array_size; + u32 mask; + u32 pad; + u64 highest; + u64 array[SEQNO_WINDOW_ARRAY_SIZE]; /* Will be alloc to array_size */ +} seqno_bitmap; + +typedef struct seqno_rx_info_ +{ + u64 rx_packets; + u64 lost_packets; + u64 reordered_packets; + u64 dup_packets; + seqno_bitmap bitmap; +} seqno_rx_info; + +/* This structure is 64-byte aligned */ +typedef struct ioam_seqno_data_ +{ + union + { + u32 seq_num; /* Useful only for encap node */ + seqno_rx_info seqno_rx; + }; +} ioam_seqno_data; + +static inline void +BIT_SET (u64 * p, u32 n) +{ + p[n >> 5] |= (1 << (n & 31)); +} + +static inline int +BIT_TEST (u64 * p, u32 n) +{ + return p[n >> 5] & (1 << (n & 31)); +} + +static void +BIT_CLEAR (u64 * p, u64 start, int num_bits, u32 mask) +{ + int n, t; + int start_index = (start >> 5); + int mask_index = (mask >> 5); + + start_index &= mask_index; + if (start & 0x1f) + { + int start_bit = (start & 0x1f); + + n = (1 << start_bit) - 1; + t = start_bit + num_bits; + if (t < 32) + { + n |= ~((1 << t) - 1); + p[start_index] &= n; + return; + } + p[start_index] &= n; + start_index = (start_index + 1) & mask_index; + num_bits -= (32 - start_bit); + } + while (num_bits >= 32) + { + p[start_index] = 0; + start_index = (start_index + 1) & mask_index; + num_bits -= 32; + } + n = ~((1 << num_bits) - 1); + p[start_index] &= n; +} + +static inline u8 +seqno_check_wraparound (u32 a, u32 b) +{ + if ((a != b) && (a > b) && ((a - b) > SEQ_CHECK_VALUE)) + { + return 1; + } + return 0; +} + +/* + * Function to analyze the PPC value recevied. + * - Updates the bitmap with received sequence number + * - counts the received/lost/duplicate/reordered packets + */ +inline static void +ioam_analyze_seqno (seqno_rx_info * seqno_rx, u64 seqno) +{ + int diff; + static int peer_dead_count; + seqno_bitmap *bitmap = &seqno_rx->bitmap; + + seqno_rx->rx_packets++; + + if (seqno > bitmap->highest) + { /* new larger sequence number */ + peer_dead_count = 0; + diff = seqno - bitmap->highest; + if (diff < bitmap->window_size) + { + if (diff > 1) + { /* diff==1 is *such* a common case it's a win to optimize it */ + BIT_CLEAR (bitmap->array, bitmap->highest + 1, diff - 1, + bitmap->mask); + seqno_rx->lost_packets += diff - 1; + } + } + else + { + seqno_rx->lost_packets += diff - 1; + memset (bitmap->array, 0, bitmap->array_size * sizeof (u64)); + } + BIT_SET (bitmap->array, seqno & bitmap->mask); + bitmap->highest = seqno; + return; + } + + /* we've seen a bigger seq number before */ + diff = bitmap->highest - seqno; + if (diff >= bitmap->window_size) + { + if (seqno_check_wraparound (bitmap->highest, seqno)) + { + memset (bitmap->array, 0, bitmap->array_size * sizeof (u64)); + BIT_SET (bitmap->array, seqno & bitmap->mask); + bitmap->highest = seqno; + return; + } + else + { + peer_dead_count++; + if (peer_dead_count > 25) + { + peer_dead_count = 0; + memset (bitmap->array, 0, bitmap->array_size * sizeof (u64)); + BIT_SET (bitmap->array, seqno & bitmap->mask); + bitmap->highest = seqno; + } + //ppc_rx->reordered_packets++; + } + return; + } + + if (BIT_TEST (bitmap->array, seqno & bitmap->mask)) + { + seqno_rx->dup_packets++; + return; /* Already seen */ + } + seqno_rx->reordered_packets++; + seqno_rx->lost_packets--; + BIT_SET (bitmap->array, seqno & bitmap->mask); + return; +} + +u8 *show_ioam_seqno_analyse_data_fn (u8 * s, seqno_rx_info * rx); + +u8 *show_ioam_seqno_cmd_fn (u8 * s, ioam_seqno_data * seqno_data, u8 enc); + +void ioam_seqno_init_data (ioam_seqno_data * data); + +void ioam_seqno_init_rx_info (seqno_rx_info * data); + +#endif /* PLUGINS_IOAM_PLUGIN_IOAM_LIB_E2E_IOAM_SEQNO_LIB_H_ */ + +/* + * fd.io coding-style-patch-verification: ON + * + * Local Variables: + * eval: (c-set-style "gnu") + * End: + */ -- cgit 1.2.3-korg