2 * Copyright (c) 2016 Cisco and/or its affiliates.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at:
7 * http://www.apache.org/licenses/LICENSE-2.0
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
16 #ifndef PLUGINS_IOAM_PLUGIN_IOAM_LIB_E2E_IOAM_SEQNO_LIB_H_
17 #define PLUGINS_IOAM_PLUGIN_IOAM_LIB_E2E_IOAM_SEQNO_LIB_H_
19 #include <vppinfra/types.h>
21 #define SEQ_CHECK_VALUE 0x80000000 /* for seq number wraparound detection */
23 #define SEQNO_WINDOW_SIZE 2048
24 #define SEQNO_WINDOW_ARRAY_SIZE 64
26 typedef struct seqno_bitmap_
33 u64 array[SEQNO_WINDOW_ARRAY_SIZE]; /* Will be alloc to array_size */
36 typedef struct seqno_rx_info_
40 u64 reordered_packets;
45 /* This structure is 64-byte aligned */
46 typedef struct ioam_seqno_data_
50 u32 seq_num; /* Useful only for encap node */
51 seqno_rx_info seqno_rx;
56 BIT_SET (u64 * p, u32 n)
58 p[n >> 5] |= (1 << (n & 31));
62 BIT_TEST (u64 * p, u32 n)
64 return p[n >> 5] & (1 << (n & 31));
68 BIT_CLEAR (u64 * p, u64 start, int num_bits, u32 mask)
71 int start_index = (start >> 5);
72 int mask_index = (mask >> 5);
74 start_index &= mask_index;
77 int start_bit = (start & 0x1f);
79 n = (1 << start_bit) - 1;
80 t = start_bit + num_bits;
88 start_index = (start_index + 1) & mask_index;
89 num_bits -= (32 - start_bit);
91 while (num_bits >= 32)
94 start_index = (start_index + 1) & mask_index;
97 n = ~((1 << num_bits) - 1);
102 seqno_check_wraparound (u32 a, u32 b)
104 if ((a != b) && (a > b) && ((a - b) > SEQ_CHECK_VALUE))
112 * Function to analyze the PPC value recevied.
113 * - Updates the bitmap with received sequence number
114 * - counts the received/lost/duplicate/reordered packets
117 ioam_analyze_seqno (seqno_rx_info * seqno_rx, u64 seqno)
120 static int peer_dead_count;
121 seqno_bitmap *bitmap = &seqno_rx->bitmap;
123 seqno_rx->rx_packets++;
125 if (seqno > bitmap->highest)
126 { /* new larger sequence number */
128 diff = seqno - bitmap->highest;
129 if (diff < bitmap->window_size)
132 { /* diff==1 is *such* a common case it's a win to optimize it */
133 BIT_CLEAR (bitmap->array, bitmap->highest + 1, diff - 1,
135 seqno_rx->lost_packets += diff - 1;
140 seqno_rx->lost_packets += diff - 1;
141 memset (bitmap->array, 0, bitmap->array_size * sizeof (u64));
143 BIT_SET (bitmap->array, seqno & bitmap->mask);
144 bitmap->highest = seqno;
148 /* we've seen a bigger seq number before */
149 diff = bitmap->highest - seqno;
150 if (diff >= bitmap->window_size)
152 if (seqno_check_wraparound (bitmap->highest, seqno))
154 memset (bitmap->array, 0, bitmap->array_size * sizeof (u64));
155 BIT_SET (bitmap->array, seqno & bitmap->mask);
156 bitmap->highest = seqno;
162 if (peer_dead_count > 25)
165 memset (bitmap->array, 0, bitmap->array_size * sizeof (u64));
166 BIT_SET (bitmap->array, seqno & bitmap->mask);
167 bitmap->highest = seqno;
169 //ppc_rx->reordered_packets++;
174 if (BIT_TEST (bitmap->array, seqno & bitmap->mask))
176 seqno_rx->dup_packets++;
177 return; /* Already seen */
179 seqno_rx->reordered_packets++;
180 seqno_rx->lost_packets--;
181 BIT_SET (bitmap->array, seqno & bitmap->mask);
185 u8 *show_ioam_seqno_analyse_data_fn (u8 * s, seqno_rx_info * rx);
187 u8 *show_ioam_seqno_cmd_fn (u8 * s, ioam_seqno_data * seqno_data, u8 enc);
189 void ioam_seqno_init_data (ioam_seqno_data * data);
191 void ioam_seqno_init_rx_info (seqno_rx_info * data);
193 #endif /* PLUGINS_IOAM_PLUGIN_IOAM_LIB_E2E_IOAM_SEQNO_LIB_H_ */
196 * fd.io coding-style-patch-verification: ON
199 * eval: (c-set-style "gnu")