LCOV - code coverage report
Current view: top level - plugins/ioam/lib-e2e - ioam_seqno_lib.h (source / functions) Hit Total Coverage
Test: coverage-filtered.info Lines: 0 66 0.0 %
Date: 2023-07-05 22:20:52 Functions: 0 5 0.0 %

          Line data    Source code
       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             : {
      28             :   u32 window_size;
      29             :   u32 array_size;
      30             :   u32 mask;
      31             :   u32 pad;
      32             :   u64 highest;
      33             :   u64 array[SEQNO_WINDOW_ARRAY_SIZE];   /* Will be alloc to array_size */
      34             : } seqno_bitmap;
      35             : 
      36             : typedef struct seqno_rx_info_
      37             : {
      38             :   u64 rx_packets;
      39             :   u64 lost_packets;
      40             :   u64 reordered_packets;
      41             :   u64 dup_packets;
      42             :   seqno_bitmap bitmap;
      43             : } seqno_rx_info;
      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 */
      51             :     seqno_rx_info seqno_rx;
      52             :   };
      53             : } ioam_seqno_data;
      54             : 
      55             : static inline void
      56           0 : BIT_SET (u64 * p, u32 n)
      57             : {
      58           0 :   p[n >> 5] |= (1 << (n & 31));
      59           0 : }
      60             : 
      61             : static inline int
      62           0 : BIT_TEST (u64 * p, u32 n)
      63             : {
      64           0 :   return p[n >> 5] & (1 << (n & 31));
      65             : }
      66             : 
      67             : static void
      68           0 : BIT_CLEAR (u64 * p, u64 start, int num_bits, u32 mask)
      69             : {
      70             :   int n, t;
      71           0 :   int start_index = (start >> 5);
      72           0 :   int mask_index = (mask >> 5);
      73             : 
      74           0 :   start_index &= mask_index;
      75           0 :   if (start & 0x1f)
      76             :     {
      77           0 :       int start_bit = (start & 0x1f);
      78             : 
      79           0 :       n = (1 << start_bit) - 1;
      80           0 :       t = start_bit + num_bits;
      81           0 :       if (t < 32)
      82             :         {
      83           0 :           n |= ~((1 << t) - 1);
      84           0 :           p[start_index] &= n;
      85           0 :           return;
      86             :         }
      87           0 :       p[start_index] &= n;
      88           0 :       start_index = (start_index + 1) & mask_index;
      89           0 :       num_bits -= (32 - start_bit);
      90             :     }
      91           0 :   while (num_bits >= 32)
      92             :     {
      93           0 :       p[start_index] = 0;
      94           0 :       start_index = (start_index + 1) & mask_index;
      95           0 :       num_bits -= 32;
      96             :     }
      97           0 :   n = ~((1 << num_bits) - 1);
      98           0 :   p[start_index] &= n;
      99             : }
     100             : 
     101             : static inline u8
     102           0 : seqno_check_wraparound (u32 a, u32 b)
     103             : {
     104           0 :   if ((a != b) && (a > b) && ((a - b) > SEQ_CHECK_VALUE))
     105             :     {
     106           0 :       return 1;
     107             :     }
     108           0 :   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
     117           0 : ioam_analyze_seqno (seqno_rx_info * seqno_rx, u64 seqno)
     118             : {
     119             :   int diff;
     120             :   static int peer_dead_count;
     121           0 :   seqno_bitmap *bitmap = &seqno_rx->bitmap;
     122             : 
     123           0 :   seqno_rx->rx_packets++;
     124             : 
     125           0 :   if (seqno > bitmap->highest)
     126             :     {                           /* new larger sequence number */
     127           0 :       peer_dead_count = 0;
     128           0 :       diff = seqno - bitmap->highest;
     129           0 :       if (diff < bitmap->window_size)
     130             :         {
     131           0 :           if (diff > 1)
     132             :             {                   /* diff==1 is *such* a common case it's a win to optimize it */
     133           0 :               BIT_CLEAR (bitmap->array, bitmap->highest + 1, diff - 1,
     134             :                          bitmap->mask);
     135           0 :               seqno_rx->lost_packets += diff - 1;
     136             :             }
     137             :         }
     138             :       else
     139             :         {
     140           0 :           seqno_rx->lost_packets += diff - 1;
     141           0 :           clib_memset (bitmap->array, 0, bitmap->array_size * sizeof (u64));
     142             :         }
     143           0 :       BIT_SET (bitmap->array, seqno & bitmap->mask);
     144           0 :       bitmap->highest = seqno;
     145           0 :       return;
     146             :     }
     147             : 
     148             :   /* we've seen a bigger seq number before */
     149           0 :   diff = bitmap->highest - seqno;
     150           0 :   if (diff >= bitmap->window_size)
     151             :     {
     152           0 :       if (seqno_check_wraparound (bitmap->highest, seqno))
     153             :         {
     154           0 :           clib_memset (bitmap->array, 0, bitmap->array_size * sizeof (u64));
     155           0 :           BIT_SET (bitmap->array, seqno & bitmap->mask);
     156           0 :           bitmap->highest = seqno;
     157           0 :           return;
     158             :         }
     159             :       else
     160             :         {
     161           0 :           peer_dead_count++;
     162           0 :           if (peer_dead_count > 25)
     163             :             {
     164           0 :               peer_dead_count = 0;
     165           0 :               clib_memset (bitmap->array, 0,
     166             :                            bitmap->array_size * sizeof (u64));
     167           0 :               BIT_SET (bitmap->array, seqno & bitmap->mask);
     168           0 :               bitmap->highest = seqno;
     169             :             }
     170             :           //ppc_rx->reordered_packets++;
     171             :         }
     172           0 :       return;
     173             :     }
     174             : 
     175           0 :   if (BIT_TEST (bitmap->array, seqno & bitmap->mask))
     176             :     {
     177           0 :       seqno_rx->dup_packets++;
     178           0 :       return;                   /* Already seen */
     179             :     }
     180           0 :   seqno_rx->reordered_packets++;
     181           0 :   seqno_rx->lost_packets--;
     182           0 :   BIT_SET (bitmap->array, seqno & bitmap->mask);
     183           0 :   return;
     184             : }
     185             : 
     186             : u8 *show_ioam_seqno_analyse_data_fn (u8 * s, seqno_rx_info * rx);
     187             : 
     188             : u8 *show_ioam_seqno_cmd_fn (u8 * s, ioam_seqno_data * seqno_data, u8 enc);
     189             : 
     190             : void ioam_seqno_init_data (ioam_seqno_data * data);
     191             : 
     192             : void ioam_seqno_init_rx_info (seqno_rx_info * data);
     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             :  */

Generated by: LCOV version 1.14