FD.io VPP  v21.01.1
Vector Packet Processing
ioam_seqno_lib.h
Go to the documentation of this file.
1 /*
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:
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
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.
14  */
15 
16 #ifndef PLUGINS_IOAM_PLUGIN_IOAM_LIB_E2E_IOAM_SEQNO_LIB_H_
17 #define PLUGINS_IOAM_PLUGIN_IOAM_LIB_E2E_IOAM_SEQNO_LIB_H_
18 
19 #include <vppinfra/types.h>
20 
21 #define SEQ_CHECK_VALUE 0x80000000 /* for seq number wraparound detection */
22 
23 #define SEQNO_WINDOW_SIZE 2048
24 #define SEQNO_WINDOW_ARRAY_SIZE 64
25 
26 typedef struct seqno_bitmap_
27 {
33  u64 array[SEQNO_WINDOW_ARRAY_SIZE]; /* Will be alloc to array_size */
34 } seqno_bitmap;
35 
36 typedef struct seqno_rx_info_
37 {
44 
45 /* This structure is 64-byte aligned */
46 typedef struct ioam_seqno_data_
47 {
48  union
49  {
50  u32 seq_num; /* Useful only for encap node */
52  };
54 
55 static inline void
56 BIT_SET (u64 * p, u32 n)
57 {
58  p[n >> 5] |= (1 << (n & 31));
59 }
60 
61 static inline int
62 BIT_TEST (u64 * p, u32 n)
63 {
64  return p[n >> 5] & (1 << (n & 31));
65 }
66 
67 static void
68 BIT_CLEAR (u64 * p, u64 start, int num_bits, u32 mask)
69 {
70  int n, t;
71  int start_index = (start >> 5);
72  int mask_index = (mask >> 5);
73 
74  start_index &= mask_index;
75  if (start & 0x1f)
76  {
77  int start_bit = (start & 0x1f);
78 
79  n = (1 << start_bit) - 1;
80  t = start_bit + num_bits;
81  if (t < 32)
82  {
83  n |= ~((1 << t) - 1);
84  p[start_index] &= n;
85  return;
86  }
87  p[start_index] &= n;
88  start_index = (start_index + 1) & mask_index;
89  num_bits -= (32 - start_bit);
90  }
91  while (num_bits >= 32)
92  {
93  p[start_index] = 0;
94  start_index = (start_index + 1) & mask_index;
95  num_bits -= 32;
96  }
97  n = ~((1 << num_bits) - 1);
98  p[start_index] &= n;
99 }
100 
101 static inline u8
103 {
104  if ((a != b) && (a > b) && ((a - b) > SEQ_CHECK_VALUE))
105  {
106  return 1;
107  }
108  return 0;
109 }
110 
111 /*
112  * Function to analyze the PPC value recevied.
113  * - Updates the bitmap with received sequence number
114  * - counts the received/lost/duplicate/reordered packets
115  */
116 inline static void
118 {
119  int diff;
120  static int peer_dead_count;
121  seqno_bitmap *bitmap = &seqno_rx->bitmap;
122 
123  seqno_rx->rx_packets++;
124 
125  if (seqno > bitmap->highest)
126  { /* new larger sequence number */
127  peer_dead_count = 0;
128  diff = seqno - bitmap->highest;
129  if (diff < bitmap->window_size)
130  {
131  if (diff > 1)
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,
134  bitmap->mask);
135  seqno_rx->lost_packets += diff - 1;
136  }
137  }
138  else
139  {
140  seqno_rx->lost_packets += diff - 1;
141  clib_memset (bitmap->array, 0, bitmap->array_size * sizeof (u64));
142  }
143  BIT_SET (bitmap->array, seqno & bitmap->mask);
144  bitmap->highest = seqno;
145  return;
146  }
147 
148  /* we've seen a bigger seq number before */
149  diff = bitmap->highest - seqno;
150  if (diff >= bitmap->window_size)
151  {
152  if (seqno_check_wraparound (bitmap->highest, seqno))
153  {
154  clib_memset (bitmap->array, 0, bitmap->array_size * sizeof (u64));
155  BIT_SET (bitmap->array, seqno & bitmap->mask);
156  bitmap->highest = seqno;
157  return;
158  }
159  else
160  {
161  peer_dead_count++;
162  if (peer_dead_count > 25)
163  {
164  peer_dead_count = 0;
165  clib_memset (bitmap->array, 0,
166  bitmap->array_size * sizeof (u64));
167  BIT_SET (bitmap->array, seqno & bitmap->mask);
168  bitmap->highest = seqno;
169  }
170  //ppc_rx->reordered_packets++;
171  }
172  return;
173  }
174 
175  if (BIT_TEST (bitmap->array, seqno & bitmap->mask))
176  {
177  seqno_rx->dup_packets++;
178  return; /* Already seen */
179  }
180  seqno_rx->reordered_packets++;
181  seqno_rx->lost_packets--;
182  BIT_SET (bitmap->array, seqno & bitmap->mask);
183  return;
184 }
185 
187 
188 u8 *show_ioam_seqno_cmd_fn (u8 * s, ioam_seqno_data * seqno_data, u8 enc);
189 
191 
193 
194 #endif /* PLUGINS_IOAM_PLUGIN_IOAM_LIB_E2E_IOAM_SEQNO_LIB_H_ */
195 
196 /*
197  * fd.io coding-style-patch-verification: ON
198  *
199  * Local Variables:
200  * eval: (c-set-style "gnu")
201  * End:
202  */
a
Definition: bitmap.h:544
unsigned long u64
Definition: types.h:89
clib_memset(h->entries, 0, sizeof(h->entries[0]) *entries)
#define SEQ_CHECK_VALUE
static void BIT_CLEAR(u64 *p, u64 start, int num_bits, u32 mask)
unsigned char u8
Definition: types.h:56
seqno_rx_info seqno_rx
static void ioam_analyze_seqno(seqno_rx_info *seqno_rx, u64 seqno)
struct seqno_rx_info_ seqno_rx_info
const cJSON *const b
Definition: cJSON.h:255
unsigned int u32
Definition: types.h:88
struct ioam_seqno_data_ ioam_seqno_data
struct seqno_bitmap_ seqno_bitmap
void ioam_seqno_init_rx_info(seqno_rx_info *data)
static void BIT_SET(u64 *p, u32 n)
u8 * show_ioam_seqno_cmd_fn(u8 *s, ioam_seqno_data *seqno_data, u8 enc)
void ioam_seqno_init_data(ioam_seqno_data *data)
static u8 seqno_check_wraparound(u32 a, u32 b)
#define SEQNO_WINDOW_ARRAY_SIZE
static int BIT_TEST(u64 *p, u32 n)
seqno_bitmap bitmap
u8 * show_ioam_seqno_analyse_data_fn(u8 *s, seqno_rx_info *rx)
u64 array[SEQNO_WINDOW_ARRAY_SIZE]