LCOV - code coverage report
Current view: top level - waltz/ip - fd_fib4.c (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 274 320 85.6 %
Date: 2025-12-06 04:45:29 Functions: 15 15 100.0 %

          Line data    Source code
       1             : #include "fd_fib4.h"
       2             : #include "fd_fib4_private.h"
       3             : #include "../../util/tmpl/fd_map.h"
       4             : #include "../../util/net/fd_ip4.h"  /* for printing ip4 addrs */
       5             : #define SORT_NAME sort_fib4_key
       6             : #define SORT_KEY_T fd_fib4_key_t
       7         222 : #define SORT_BEFORE(a,b) ( ((a).mask_bits<(b).mask_bits) || \
       8         222 :                          ( ((a).mask_bits==(b).mask_bits) && ((a).prio<(b).prio) ) || \
       9         222 :                          ( ((a).mask_bits==(b).mask_bits) && ((a).prio==(b).prio) && ((a).addr<(b).addr) ) )
      10             : #include "../../util/tmpl/fd_sort.c"
      11             : 
      12             : static const fd_fib4_hop_t
      13             : fd_fib4_hop_blackhole = {
      14             :   .rtype = FD_FIB4_RTYPE_BLACKHOLE
      15             : };
      16             : 
      17             : FD_FN_CONST ulong
      18          93 : fd_fib4_align( void ) {
      19          93 :   return alignof(fd_fib4_priv_t);
      20          93 : }
      21             : 
      22             : FD_FN_CONST ulong
      23             : fd_fib4_footprint( ulong route_max,
      24          33 :                    ulong route_peer_max ) {
      25          33 :   if( route_max==0 || route_max>UINT_MAX ||
      26          33 :       route_peer_max==0 || route_peer_max>UINT_MAX ) return 0UL;
      27          24 :   ulong elem_max       = fd_fib4_hmap_get_ele_max( route_peer_max   );
      28          24 :   ulong hmap_footprint = fd_fib4_hmap_footprint( elem_max );
      29          24 :   if( !hmap_footprint ) return 0UL;
      30             : 
      31          24 :   return FD_LAYOUT_FINI( FD_LAYOUT_APPEND( FD_LAYOUT_APPEND( FD_LAYOUT_APPEND( FD_LAYOUT_APPEND( FD_LAYOUT_INIT,
      32          24 :       alignof(fd_fib4_priv_t),       sizeof(fd_fib4_priv_t)                ),
      33          24 :       alignof(fd_fib4_key_t),        route_max*sizeof(fd_fib4_key_t)       ),
      34          24 :       alignof(fd_fib4_hop_t),        route_max*sizeof(fd_fib4_hop_t)       ),
      35          24 :       fd_fib4_hmap_align(),          hmap_footprint                        ),
      36          24 :       fd_fib4_align() );
      37          24 : }
      38             : 
      39             : void *
      40             : fd_fib4_new( void * mem,
      41             :              ulong  route_max,
      42             :              ulong  route_peer_max,
      43          18 :              ulong  route_peer_seed ) {
      44             : 
      45          18 :   if( FD_UNLIKELY( !mem ) ) {
      46           0 :     FD_LOG_WARNING(( "NULL mem" ));
      47           0 :     return NULL;
      48           0 :   }
      49          18 :   if( FD_UNLIKELY( !fd_ulong_is_aligned( (ulong)mem, fd_fib4_align() ) ) ) {
      50           0 :     FD_LOG_WARNING(( "unaligned mem" ));
      51           0 :     return NULL;
      52           0 :   }
      53          18 :   if( FD_UNLIKELY( route_max==0 || route_max>UINT_MAX ) ) {
      54           0 :     FD_LOG_WARNING(( "invalid route_max" ));
      55           0 :     return NULL;
      56           0 :   }
      57          18 :   if( FD_UNLIKELY( route_peer_max==0 || route_peer_max>UINT_MAX ) ) {
      58           0 :     FD_LOG_WARNING(( "invalid route_peer_max" ));
      59           0 :     return NULL;
      60           0 :   }
      61             : 
      62          18 :   FD_SCRATCH_ALLOC_INIT( l, mem );
      63          18 :   fd_fib4_priv_t * fib4  = FD_SCRATCH_ALLOC_APPEND( l, alignof(fd_fib4_priv_t), sizeof(fd_fib4_priv_t)         );
      64          18 :   fd_fib4_key_t  * keys  = FD_SCRATCH_ALLOC_APPEND( l, alignof(fd_fib4_key_t), route_max*sizeof(fd_fib4_key_t) );
      65          18 :   fd_fib4_hop_t  * vals  = FD_SCRATCH_ALLOC_APPEND( l, alignof(fd_fib4_hop_t), route_max*sizeof(fd_fib4_hop_t) );
      66           0 :   ulong  hmap_elem_max   = fd_fib4_hmap_get_ele_max( route_peer_max );
      67          18 :   ulong  hmap_footprint  = fd_fib4_hmap_footprint( hmap_elem_max ); FD_TEST( hmap_footprint );
      68          18 :   void * fib4_hmap_mem   = FD_SCRATCH_ALLOC_APPEND( l, fd_fib4_hmap_align(), hmap_footprint ); FD_TEST( fib4_hmap_mem );
      69          18 :   FD_SCRATCH_ALLOC_FINI( l, alignof(fd_fib4_priv_t) );
      70             : 
      71          18 :   fd_memset( fib4, 0, sizeof(fd_fib4_priv_t)          );
      72          18 :   fd_memset( keys, 0, route_max*sizeof(fd_fib4_key_t) );
      73          18 :   fd_memset( vals, 0, route_max*sizeof(fd_fib4_hop_t) );
      74             : 
      75          18 :   FD_TEST( fd_fib4_hmap_new( fib4_hmap_mem, hmap_elem_max, 1 ) );
      76             : 
      77          18 :   fib4->cnt              = 1UL;   // first route entry is 0.0.0.0/0
      78          18 :   fib4->max              = route_max;
      79          18 :   fib4->hop_off          = (ulong)vals - (ulong)fib4;
      80          18 :   fib4->hmap_offset      = (ulong)fib4_hmap_mem - (ulong)fib4;
      81          18 :   fib4->hmap_max         = route_peer_max;
      82          18 :   fib4->hmap_cnt         = 0;
      83          18 :   fib4->seed             = route_peer_seed;
      84          18 :   keys[0].prio           = UINT_MAX;
      85          18 :   vals[0].rtype          = FD_FIB4_RTYPE_THROW;
      86          18 :   keys[0].mask_bits      = 32;
      87             : 
      88          18 :   return fib4;
      89          18 : }
      90             : 
      91             : fd_fib4_t *
      92             : fd_fib4_join( fd_fib4_t * join,
      93          18 :               void *      shmem ) {
      94          18 :   if( FD_UNLIKELY( !join ) ) {
      95           0 :     FD_LOG_WARNING(( "NULL join" ));
      96           0 :     return NULL;
      97           0 :   }
      98          18 :   if( FD_UNLIKELY( !shmem ) ) {
      99           0 :     FD_LOG_WARNING(( "NULL shmem" ));
     100           0 :     return NULL;
     101           0 :   }
     102             : 
     103          18 :   if( FD_UNLIKELY( !fd_ulong_is_aligned( (ulong)shmem, fd_fib4_align() ) ) ) {
     104           0 :     FD_LOG_WARNING(( "unaligned shmem" ));
     105           0 :     return NULL;
     106           0 :   }
     107             : 
     108          18 :   fd_fib4_priv_t * priv       =  fd_type_pun( shmem );
     109          18 :   fd_fib4_hmap_t * hmap_join  =  fd_type_pun( join->hmap_join );
     110          18 :   void *           hmap_mem   =  fd_fib4_hmap_mem( priv );
     111          18 :   ulong            ele_max    =  fd_fib4_hmap_get_ele_max( priv->hmap_max );
     112          18 :   ulong            probe_max  =  fd_fib4_hmap_get_probe_max( ele_max );
     113          18 :   ulong            seed       =  priv->seed;
     114             : 
     115          18 :   FD_TEST( fd_fib4_hmap_join( hmap_join, hmap_mem, ele_max, probe_max, seed ) );
     116             : 
     117          18 :   join->priv = priv;
     118          18 :   return join;
     119          18 : }
     120             : 
     121             : void *
     122          12 : fd_fib4_leave( fd_fib4_t * fib4 ) {
     123          12 :   *fib4 = (fd_fib4_t){0};
     124          12 :   return fib4;
     125          12 : }
     126             : 
     127             : void *
     128          12 : fd_fib4_delete( void * mem ) {
     129          12 :   return mem;
     130          12 : }
     131             : 
     132             : void
     133          69 : fd_fib4_clear( fd_fib4_t * fib4_join ) {
     134          69 :   fd_fib4_priv_t * fib4 = fib4_join->priv;
     135          69 :   fib4->cnt = 1UL;
     136             : 
     137          69 :   if( fib4->hmap_cnt==0 ) return;
     138             : 
     139             : 
     140          45 :   fib4->hmap_cnt = 0;
     141          45 :   fd_fib4_hmap_t * hmap_join = fd_type_pun( fib4_join->hmap_join );
     142          45 :   void *           hmap_mem  = fd_fib4_hmap_mem( fib4 );
     143          45 :   ulong            elem_max  = fd_fib4_hmap_get_ele_max( fib4->hmap_max );
     144          45 :   FD_TEST( fd_fib4_hmap_leave( hmap_join ) );
     145          45 :   FD_TEST( fd_fib4_hmap_new( hmap_mem, elem_max, 1 ) );
     146             : 
     147          45 :   ulong            probe_max = fd_fib4_hmap_get_probe_max( elem_max );
     148          45 :   ulong            seed      = fib4->seed;
     149          45 :   FD_TEST( fd_fib4_hmap_join( hmap_join, hmap_mem, elem_max, probe_max, seed ) );
     150          45 : }
     151             : 
     152             : FD_FN_PURE ulong
     153           6 : fd_fib4_max( fd_fib4_t const * fib4_join ) {
     154           6 :   return fib4_join->priv->max;
     155           6 : }
     156             : 
     157             : FD_FN_PURE ulong
     158           6 : fd_fib4_peer_max( fd_fib4_t const * fib4_join ) {
     159           6 :   return fib4_join->priv->hmap_max;
     160           6 : }
     161             : 
     162             : FD_FN_PURE ulong
     163          39 : fd_fib4_cnt( fd_fib4_t const * fib4_join ) {
     164          39 :   fd_fib4_priv_t * priv = fib4_join->priv;
     165          39 :   return priv->cnt+priv->hmap_cnt;
     166          39 : }
     167             : 
     168             : /* fd_fib4_hmap_insert adds a new entry (key=ip4_dst, value=hop) to the fib4
     169             :    hmap. Assume the netmask for the ip4_dst entry is 32, and ip4_dst is not 0.
     170             :    Return FD_MAP_SUCCESS on success, FD_MAP_ERR_FULL if the hmap is full.
     171             : */
     172             : 
     173             : static int
     174             : fd_fib4_hmap_insert_entry( fd_fib4_t *     fib4_join,
     175             :                            uint            ip4_dst,
     176         246 :                            fd_fib4_hop_t * hop ) {
     177             : 
     178         246 :   FD_TEST( hop );
     179         246 :   fd_fib4_priv_t * fib = fib4_join->priv;
     180         246 :   if( FD_UNLIKELY( fib->hmap_cnt>=fib->hmap_max ) ) return FD_MAP_ERR_FULL;
     181             : 
     182         240 :   fd_fib4_hmap_t * hmap_join = fd_type_pun( fib4_join->hmap_join );
     183             : 
     184         240 :   uint key = ip4_dst;
     185         240 :   fd_fib4_hmap_entry_t * ele = fd_fib4_hmap_upsert( hmap_join, &key );
     186         240 :   if( FD_UNLIKELY( !ele ) ) return FD_MAP_ERR_FULL;
     187         240 :   fd_fib4_hmap_entry_t to_enter = {
     188         240 :     .dst_addr = ip4_dst,
     189         240 :     .hash     = fd_fib4_hmap_entry_hash( ip4_dst, fib->seed ),
     190         240 :     .next_hop = *hop
     191         240 :   };
     192         240 :   fd_fib4_hmap_entry_st( ele, &to_enter );
     193             : 
     194         240 :   fib->hmap_cnt++;
     195             : 
     196         240 :   return FD_MAP_SUCCESS;
     197         240 : }
     198             : 
     199             : int
     200             : fd_fib4_insert( fd_fib4_t *     fib_join,
     201             :                 uint            ip4_dst,
     202             :                 int             prefix,
     203             :                 uint            prio,
     204         396 :                 fd_fib4_hop_t * hop ) {
     205             : 
     206         396 :   FD_TEST( hop );
     207         396 :   if( ip4_dst!=0 && prefix==32 ) {
     208         246 :     if( fd_fib4_hmap_insert_entry( fib_join, ip4_dst, hop )==FD_MAP_SUCCESS ) return 1;
     209           6 :     FD_LOG_WARNING(( "Failed to insert /32 route " FD_IP4_ADDR_FMT " into fib4 hashmap", FD_IP4_ADDR_FMT_ARGS(ip4_dst) ));
     210           6 :     return 0;
     211         246 :   }
     212             : 
     213         150 :   fd_fib4_priv_t * fib = fib_join->priv;
     214             : 
     215         150 :   ulong const generation = fib->generation;
     216             : 
     217         150 :   if( FD_UNLIKELY( fib->cnt>=fib->max ) ) {
     218           6 :     FD_LOG_WARNING(( "Failed to insert route " FD_IP4_ADDR_FMT ", route table is full (%lu max)", FD_IP4_ADDR_FMT_ARGS(ip4_dst), fib->max ));
     219           6 :     return 0;
     220           6 :   }
     221             : 
     222         144 :   FD_COMPILER_MFENCE();
     223         144 :   fib->generation = generation+1UL;
     224         144 :   FD_COMPILER_MFENCE();
     225             : 
     226         144 :   ulong old_cnt = fib->cnt;
     227         144 :   fib->cnt      = old_cnt+1UL;
     228             : 
     229         144 :   uint mask = prefix>0 ? fd_uint_mask( 32-prefix, 31 ) : 0U;
     230             : 
     231         144 :   fd_fib4_key_t new_key = (fd_fib4_key_t){
     232         144 :     .addr      = fd_uint_bswap( ip4_dst ) & mask,
     233         144 :     .mask      = mask,
     234         144 :     .prio      = prio,
     235         144 :     .mask_bits = fd_uint_find_lsb_w_default( mask, 32 )
     236         144 :   };
     237             : 
     238         144 :   fd_fib4_key_t * key_tbl = fd_fib4_key_tbl( fib );
     239         144 :   fd_fib4_hop_t * hop_tbl = fd_fib4_hop_tbl( fib );
     240             : 
     241             :   /* Maintain sorted order for indices [1,cnt) by (mask_bits, prio) ascending.
     242             :      Find the intended location and shift the rest down */
     243         144 :   ulong n_sorted = fd_ulong_sat_sub( old_cnt, 1 ); /* number of existing sorted elems in [1,idx) */
     244         144 :   ulong idx; /* loc to insert new entry */
     245         144 :   if( FD_LIKELY( n_sorted>0UL ) ) {
     246          99 :     ulong rnk = sort_fib4_key_split( key_tbl + 1UL, n_sorted, new_key );
     247          99 :     ulong pos = 1UL + rnk;
     248         111 :     for( ulong dst=old_cnt; dst>pos; dst-- ) { /* n_sorted>0 <> idx>0 */
     249          12 :       key_tbl[ dst ] = key_tbl[ dst-1 ];
     250          12 :       hop_tbl[ dst ] = hop_tbl[ dst-1 ];
     251          12 :     }
     252          99 :     idx = pos;
     253          99 :   } else {
     254          45 :     idx = old_cnt;
     255          45 :   }
     256             : 
     257         144 :   key_tbl[ idx ] = new_key;
     258         144 :   hop_tbl[ idx ] = *hop;
     259             : 
     260         144 :   FD_COMPILER_MFENCE();
     261         144 :   fib->generation = generation+2UL;
     262         144 :   FD_COMPILER_MFENCE();
     263             : 
     264         144 :   return 1;
     265         150 : }
     266             : 
     267             : fd_fib4_hop_t
     268             : fd_fib4_lookup( fd_fib4_t const * fib_join,
     269             :                 uint              ip4_dst,
     270         438 :                 ulong             flags ) {
     271         438 :   fd_fib4_priv_t * fib = fib_join->priv;
     272             : 
     273         438 :   if( FD_UNLIKELY( flags ) ) {
     274           0 :     return fd_fib4_hop_tbl_const( fib )[0]; /* dead route */
     275           0 :   }
     276             : 
     277         438 :   if( fib->hmap_cnt>0 ) {
     278         390 :     fd_fib4_hmap_t const * hmap_join = fd_type_pun_const( fib_join->hmap_join );
     279         390 :     fd_fib4_hop_t          next_hop  = fd_fib4_hmap_query_hop( hmap_join, ip4_dst );
     280         390 :     if( next_hop.rtype!=FD_FIB4_RTYPE_UNSPEC ) {
     281         213 :       return next_hop;
     282         213 :     }
     283             :     // Can't find a match in the fib4 hashmap. Look up in the routing table.
     284         390 :   }
     285             : 
     286         225 :   ip4_dst = fd_uint_bswap( ip4_dst );
     287         225 :   fd_fib4_key_t const * keys = fd_fib4_key_tbl_const( fib );
     288             : 
     289         225 :   ulong generation = FD_VOLATILE_CONST( fib->generation );
     290         225 :   if( FD_UNLIKELY( generation&0x1UL ) ) { /* writer is mid-update */
     291           0 :     return fd_fib4_hop_blackhole;
     292           0 :   }
     293         225 :   FD_COMPILER_MFENCE();
     294             : 
     295             :   /* The table [1,cnt) is sorted by increasing mask_bits then prio.
     296             :      Return the first match, which is guaranteed to be optimal. */
     297         225 :   ulong cnt = fib->cnt;
     298         225 :   ulong j   = 1UL;
     299        1074 :   while( j<cnt ) {
     300         999 :     if( (ip4_dst & keys[j].mask)==keys[j].addr ) {
     301         150 :       break;
     302         150 :     }
     303         849 :     j++;
     304         849 :   }
     305             : 
     306         225 :   ulong         idx = j==cnt ? 0UL : j;
     307         225 :   fd_fib4_hop_t out = fd_fib4_hop_tbl_const( fib )[ idx ];
     308             : 
     309         225 :   FD_COMPILER_MFENCE();
     310         225 :   if( FD_UNLIKELY( FD_VOLATILE_CONST( fib->generation )!=generation ) ) {
     311           0 :     return fd_fib4_hop_blackhole; /* torn read */
     312           0 :   }
     313         225 :   return out;
     314         225 : }
     315             : 
     316             : #if FD_HAS_HOSTED
     317             : 
     318             : #include <errno.h>
     319             : #include <stdio.h>
     320             : #include "../../util/net/fd_ip4.h"
     321             : 
     322         144 : #define WRAP_PRINT(file,str) if( FD_UNLIKELY( fputs( (str), (file) )<0 ) ) return errno
     323         195 : #define WRAP_PRINTF(file,...) if( FD_UNLIKELY( fprintf( (file), __VA_ARGS__ )<0 ) ) return errno
     324             : 
     325             : static int
     326             : fd_fib4_fprintf_route( fd_fib4_key_t const * key,
     327             :                        fd_fib4_hop_t const * hop,
     328          57 :                        FILE *                file ) {
     329             : 
     330          57 :   switch( hop->rtype ) {
     331           0 :   case FD_FIB4_RTYPE_UNSPEC:
     332           0 :     WRAP_PRINT( file, "unspecified " );
     333           0 :     break;
     334          12 :   case FD_FIB4_RTYPE_UNICAST:
     335          12 :     break;
     336          18 :   case FD_FIB4_RTYPE_LOCAL:
     337          18 :     WRAP_PRINT( file, "local " );
     338          18 :     break;
     339          18 :   case FD_FIB4_RTYPE_BROADCAST:
     340          15 :     WRAP_PRINT( file, "broadcast " );
     341          15 :     break;
     342          15 :   case FD_FIB4_RTYPE_MULTICAST:
     343           0 :     WRAP_PRINT( file, "multicast " );
     344           0 :     break;
     345           0 :   case FD_FIB4_RTYPE_BLACKHOLE:
     346           0 :     WRAP_PRINT( file, "blackhole " );
     347           0 :     break;
     348          12 :   case FD_FIB4_RTYPE_THROW:
     349          12 :     WRAP_PRINT( file, "throw " );
     350          12 :     break;
     351          12 :   default:
     352           0 :     WRAP_PRINTF( file, "invalid (%u) ", hop->rtype );
     353           0 :     break;
     354          57 :   }
     355             : 
     356          57 :   if( key->mask==0 ) {
     357          18 :     WRAP_PRINT( file, "default" );
     358          39 :   } else {
     359          39 :     WRAP_PRINTF( file, FD_IP4_ADDR_FMT, FD_IP4_ADDR_FMT_ARGS( fd_uint_bswap( key->addr ) ) );
     360          39 :     if( key->mask!=UINT_MAX ) {
     361          39 :       WRAP_PRINTF( file, "/%u", 32U-(uint)fd_uint_find_lsb_w_default( key->mask, 32 ) );
     362          39 :     }
     363          39 :   }
     364             : 
     365          57 :   if( hop->ip4_gw ) {
     366           6 :     WRAP_PRINTF( file, " via " FD_IP4_ADDR_FMT, FD_IP4_ADDR_FMT_ARGS( hop->ip4_gw ) );
     367           6 :   }
     368             : 
     369          57 :   if( hop->if_idx ) {
     370          45 :     WRAP_PRINTF( file, " dev %u", hop->if_idx );
     371          45 :   }
     372             : 
     373          57 :   switch( hop->scope ) {
     374          33 :   case 0:
     375          33 :     break;
     376           0 :   case 200:
     377           0 :     WRAP_PRINT( file, " scope site" );
     378           0 :     break;
     379          15 :   case 253:
     380          15 :     WRAP_PRINT( file, " scope link" );
     381          15 :     break;
     382          15 :   case 254:
     383           9 :     WRAP_PRINT( file, " scope host" );
     384           9 :     break;
     385           9 :   default:
     386           0 :     WRAP_PRINTF( file, " scope %u", hop->scope );
     387           0 :     break;
     388          57 :   }
     389             : 
     390          57 :   if( hop->ip4_src ) {
     391          45 :     WRAP_PRINTF( file, " src " FD_IP4_ADDR_FMT, FD_IP4_ADDR_FMT_ARGS( hop->ip4_src ) );
     392          45 :   }
     393             : 
     394          57 :   if( key->prio ) {
     395          21 :     WRAP_PRINTF( file, " metric %u", key->prio );
     396          21 :   }
     397             : 
     398          57 :   WRAP_PRINT( file, "\n" );
     399             : 
     400          57 :   return 0;
     401          57 : }
     402             : 
     403             : int
     404             : fd_fib4_fprintf( fd_fib4_t const * fib_join,
     405          12 :                  void *            file_ ) {
     406          12 :   FILE * file = file_;
     407          12 :   fd_fib4_priv_t * fib = fib_join->priv;
     408             : 
     409          12 :   fd_fib4_key_t const * key_tbl = fd_fib4_key_tbl_const( fib );
     410          12 :   fd_fib4_hop_t const * hop_tbl = fd_fib4_hop_tbl_const( fib );
     411             : 
     412          12 :   FD_COMPILER_MFENCE();
     413          12 :   ulong cnt        = fib->cnt;
     414          12 :   ulong generation = fib->generation;
     415          12 :   FD_COMPILER_MFENCE();
     416             : 
     417          45 :   for( ulong j=0UL; j<cnt; j++ ) {
     418          33 :     FD_COMPILER_MFENCE();
     419          33 :     fd_fib4_key_t key = key_tbl[j];
     420          33 :     fd_fib4_hop_t hop = hop_tbl[j];
     421          33 :     FD_COMPILER_MFENCE();
     422          33 :     ulong cur_gen = FD_VOLATILE_CONST( fib->generation );
     423          33 :     FD_COMPILER_MFENCE();
     424          33 :     if( FD_UNLIKELY( cur_gen!=generation ) ) {
     425           0 :       WRAP_PRINT( file, "=== TORN READ ===\n" );
     426           0 :       return 0;
     427           0 :     }
     428          33 :     fd_fib4_fprintf_route( &key, &hop, file );
     429          33 :   }
     430             : 
     431             :   /* Attempt to print the hashmap. */
     432          12 :   fd_fib4_hmap_t       const * hmap_join = fd_type_pun_const( fib_join->hmap_join );
     433          12 :   fd_fib4_hmap_entry_t const * elems     = fd_fib4_hmap_ele0_const( hmap_join );
     434          12 :   ulong                        ele_max   = fd_fib4_hmap_get_ele_max( fib->hmap_max );
     435        3276 :   for( ulong i=0; i<ele_max; i++ ) {
     436        3264 :     fd_fib4_hmap_entry_t const * e = elems + i;
     437        3264 :     if( FD_LIKELY( fd_fib4_hmap_ele_is_free( e ) ) ) {
     438        3240 :       continue;
     439        3240 :     }
     440             : 
     441          24 :     fd_fib4_hmap_entry_t tmp_entry;
     442          24 :     fd_fib4_hmap_entry_ld( &tmp_entry, e );
     443             : 
     444          24 :     fd_fib4_key_t key;
     445          24 :     key.addr = fd_uint_bswap( tmp_entry.dst_addr );
     446          24 :     key.mask = 31;
     447          24 :     key.prio = 0;
     448          24 :     fd_fib4_fprintf_route( &key, &tmp_entry.next_hop, file );
     449          24 :   }
     450             : 
     451          12 :   return 0;
     452          12 : }
     453             : 
     454             : #undef WRAP_PRINT
     455             : #undef WRAP_PRINTF
     456             : 
     457             : #endif /* FD_HAS_HOSTED */

Generated by: LCOV version 1.14