FD.io VPP  v16.12-rc0-308-g931be3a
Vector Packet Processing
ip6_ioam_seqno_analyse.c
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 #include <vnet/vnet.h>
17 #include "ip6_ioam_seqno.h"
18 
19 static inline void BIT_SET (u64 *p, u32 n)
20 {
21  p[ n>>5 ] |= (1 << (n&31));
22 }
23 
24 static inline int BIT_TEST (u64 *p, u32 n)
25 {
26  return p[ n>>5 ] & (1 << (n&31));
27 }
28 
29 static void BIT_CLEAR (u64 *p, u64 start, int num_bits, u32 mask)
30 {
31  int n, t;
32  int start_index = (start >> 5);
33  int mask_index = (mask >> 5);
34 
35  start_index &= mask_index;
36  if (start & 0x1f)
37  {
38  int start_bit = (start & 0x1f);
39 
40  n = (1 << start_bit)-1;
41  t = start_bit + num_bits;
42  if (t < 32)
43  {
44  n |= ~((1 << t)-1);
45  p[ start_index ] &= n;
46  return;
47  }
48  p[ start_index ] &= n;
49  start_index = (start_index + 1) & mask_index;
50  num_bits -= (32 - start_bit);
51  }
52  while (num_bits >= 32)
53  {
54  p[ start_index ] = 0;
55  start_index = (start_index + 1) & mask_index;
56  num_bits -= 32;
57  }
58  n = ~((1 << num_bits) - 1);
59  p[ start_index ] &= n;
60 }
61 
62 static inline u8 seqno_check_wraparound(u32 a, u32 b)
63 {
64  if ((a != b) && (a > b) && ((a - b) > SEQ_CHECK_VALUE))
65  {
66  return 1;
67  }
68  return 0;
69 }
70 
71 /*
72  * Function to analyze the PPC value recevied.
73  * - Updates the bitmap with received sequence number
74  * - counts the received/lost/duplicate/reordered packets
75  */
76 void ioam_analyze_seqno (seqno_rx_info *seqno_rx, u64 seqno)
77 {
78  int diff;
79  static int peer_dead_count;
80  seqno_bitmap *bitmap = &seqno_rx->bitmap;
81 
82  seqno_rx->rx_packets++;
83 
84  if (seqno > bitmap->highest)
85  { /* new larger sequence number */
86  peer_dead_count = 0;
87  diff = seqno - bitmap->highest;
88  if (diff < bitmap->window_size)
89  {
90  if (diff > 1)
91  { /* diff==1 is *such* a common case it's a win to optimize it */
92  BIT_CLEAR(bitmap->array, bitmap->highest+1, diff-1, bitmap->mask);
93  seqno_rx->lost_packets += diff -1;
94  }
95  }
96  else
97  {
98  seqno_rx->lost_packets += diff -1;
99  memset( bitmap->array, 0, bitmap->array_size * sizeof(u64) );
100  }
101  BIT_SET(bitmap->array, seqno & bitmap->mask);
102  bitmap->highest = seqno;
103  return;
104  }
105 
106  /* we've seen a bigger seq number before */
107  diff = bitmap->highest - seqno;
108  if (diff >= bitmap->window_size)
109  {
110  if (seqno_check_wraparound(bitmap->highest, seqno))
111  {
112  memset( bitmap->array, 0, bitmap->array_size * sizeof(u64));
113  BIT_SET(bitmap->array, seqno & bitmap->mask);
114  bitmap->highest = seqno;
115  return;
116  }
117  else
118  {
119  peer_dead_count++;
120  if (peer_dead_count > 25)
121  {
122  peer_dead_count = 0;
123  memset( bitmap->array, 0, bitmap->array_size * sizeof(u64) );
124  BIT_SET(bitmap->array, seqno & bitmap->mask);
125  bitmap->highest = seqno;
126  }
127  //ppc_rx->reordered_packets++;
128  }
129  return;
130  }
131 
132  if (BIT_TEST(bitmap->array, seqno & bitmap->mask))
133  {
134  seqno_rx->dup_packets++;
135  return; /* Already seen */
136  }
137  seqno_rx->reordered_packets++;
138  seqno_rx->lost_packets--;
139  BIT_SET(bitmap->array, seqno & bitmap->mask);
140  return;
141 }
#define SEQ_CHECK_VALUE
a
Definition: bitmap.h:516
unsigned long u64
Definition: types.h:89
static void BIT_SET(u64 *p, u32 n)
static u8 seqno_check_wraparound(u32 a, u32 b)
void ioam_analyze_seqno(seqno_rx_info *seqno_rx, u64 seqno)
unsigned int u32
Definition: types.h:88
unsigned char u8
Definition: types.h:56
static void BIT_CLEAR(u64 *p, u64 start, int num_bits, u32 mask)
seqno_bitmap bitmap
static int BIT_TEST(u64 *p, u32 n)
u64 array[SEQNO_WINDOW_ARRAY_SIZE]