LCOV - code coverage report
Current view: top level - waltz/mib - fd_netdev_tbl.c (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 98 146 67.1 %
Date: 2026-08-06 05:23:51 Functions: 9 10 90.0 %

          Line data    Source code
       1             : #include "fd_netdev_tbl.h"
       2             : #include "../../util/fd_util.h"
       3             : 
       4             : struct fd_netdev_tbl_private {
       5             :   ulong               magic;
       6             :   ulong               dev_off;
       7             :   ulong               bond_off;
       8             :   fd_netdev_tbl_hdr_t hdr;
       9             : };
      10             : 
      11             : FD_FN_CONST ulong
      12          12 : fd_netdev_tbl_align( void ) {
      13          12 :   return FD_NETDEV_TBL_ALIGN;
      14          12 : }
      15             : 
      16             : FD_FN_CONST ulong
      17             : fd_netdev_tbl_footprint( ulong dev_max,
      18          12 :                          ulong bond_max ) {
      19          12 :   if( FD_UNLIKELY( dev_max ==0UL || dev_max >USHORT_MAX ) ) return 0UL;
      20          12 :   if( FD_UNLIKELY( bond_max==0UL || bond_max>USHORT_MAX ) ) return 0UL;
      21          12 :   return FD_LAYOUT_FINI( FD_LAYOUT_APPEND( FD_LAYOUT_APPEND( FD_LAYOUT_APPEND( FD_LAYOUT_INIT, \
      22          12 :       alignof(fd_netdev_tbl_t),  sizeof(fd_netdev_tbl_t)             ),   \
      23          12 :       alignof(fd_netdev_t),      sizeof(fd_netdev_t)      * dev_max  ),   \
      24          12 :       alignof(fd_netdev_bond_t), sizeof(fd_netdev_bond_t) * bond_max ),   \
      25          12 :       FD_NETDEV_TBL_ALIGN );
      26          12 : }
      27             : 
      28             : void *
      29             : fd_netdev_tbl_new( void * shmem,
      30             :                    ulong  dev_max,
      31           9 :                    ulong  bond_max ) {
      32             : 
      33           9 :   if( FD_UNLIKELY( !shmem ) ) {
      34           0 :     FD_LOG_WARNING(( "NULL shmem" ));
      35           0 :     return NULL;
      36           0 :   }
      37             : 
      38           9 :   if( FD_UNLIKELY( !fd_ulong_is_aligned( (ulong)shmem, FD_NETDEV_TBL_ALIGN ) ) ) {
      39           0 :     FD_LOG_WARNING(( "misaligned shmem" ));
      40           0 :     return NULL;
      41           0 :   }
      42             : 
      43           9 :   if( FD_UNLIKELY( !dev_max || dev_max>USHORT_MAX ) ) {
      44           0 :     FD_LOG_WARNING(( "invalid dev_max" ));
      45           0 :     return NULL;
      46           0 :   }
      47             : 
      48           9 :   if( FD_UNLIKELY( !bond_max || bond_max>USHORT_MAX ) ) {
      49           0 :     FD_LOG_WARNING(( "invalid bond_max" ));
      50           0 :     return NULL;
      51           0 :   }
      52             : 
      53           9 :   FD_SCRATCH_ALLOC_INIT( l, shmem );
      54           9 :   fd_netdev_tbl_t *  tbl  = FD_SCRATCH_ALLOC_APPEND( l, alignof(fd_netdev_tbl_t),  sizeof(fd_netdev_tbl_t) );
      55           9 :   fd_netdev_t *      dev  = FD_SCRATCH_ALLOC_APPEND( l, alignof(fd_netdev_t),      sizeof(fd_netdev_t)      * dev_max  );
      56           9 :   fd_netdev_bond_t * bond = FD_SCRATCH_ALLOC_APPEND( l, alignof(fd_netdev_bond_t), sizeof(fd_netdev_bond_t) * bond_max );
      57           9 :   FD_SCRATCH_ALLOC_FINI( l, FD_NETDEV_TBL_ALIGN );
      58             : 
      59           9 :   *tbl = (fd_netdev_tbl_t) {
      60           9 :     .magic    = FD_NETDEV_TBL_MAGIC,
      61           9 :     .dev_off  = (ulong)dev  - (ulong)tbl,
      62           9 :     .bond_off = (ulong)bond - (ulong)tbl,
      63           9 :     .hdr = {
      64           9 :       .dev_max  = (ushort)dev_max,
      65           9 :       .bond_max = (ushort)bond_max,
      66           9 :       .dev_cnt  = 0,
      67           9 :       .bond_cnt = 0,
      68           9 :     }
      69           9 :   };
      70             : 
      71           9 :   fd_netdev_tbl_join_t join[1];
      72           9 :   fd_netdev_tbl_join( join, shmem );
      73           9 :   fd_netdev_tbl_reset( join );
      74           9 :   fd_netdev_tbl_leave( join );
      75             : 
      76           9 :   return tbl;
      77           9 : }
      78             : 
      79             : fd_netdev_tbl_join_t *
      80             : fd_netdev_tbl_join( void * ljoin,
      81          18 :                     void * shtbl ) {
      82             : 
      83          18 :   if( FD_UNLIKELY( !shtbl ) ) {
      84           0 :     FD_LOG_WARNING(( "NULL shtbl" ));
      85           0 :     return NULL;
      86           0 :   }
      87             : 
      88          18 :   fd_netdev_tbl_join_t * join = ljoin;
      89          18 :   fd_netdev_tbl_t *      tbl  = shtbl;
      90             : 
      91          18 :   if( FD_UNLIKELY( tbl->magic!=FD_NETDEV_TBL_MAGIC ) ) {
      92           0 :     FD_LOG_WARNING(( "bad magic" ));
      93           0 :     return NULL;
      94           0 :   }
      95             : 
      96          18 :   *join = (fd_netdev_tbl_join_t) {
      97          18 :     .hdr      = &tbl->hdr,
      98          18 :     .dev_tbl  = (fd_netdev_t      *)( (ulong)tbl + tbl->dev_off  ),
      99          18 :     .bond_tbl = (fd_netdev_bond_t *)( (ulong)tbl + tbl->bond_off ),
     100          18 :   };
     101             : 
     102          18 :   return join;
     103          18 : }
     104             : 
     105             : void *
     106          12 : fd_netdev_tbl_leave( fd_netdev_tbl_join_t * join ) {
     107          12 :   return join;
     108          12 : }
     109             : 
     110             : void *
     111           3 : fd_netdev_tbl_delete( void * shtbl ) {
     112             : 
     113           3 :   if( FD_UNLIKELY( !shtbl ) ) {
     114           0 :     FD_LOG_WARNING(( "NULL shtbl" ));
     115           0 :     return NULL;
     116           0 :   }
     117             : 
     118           3 :   fd_netdev_tbl_t * tbl = shtbl;
     119           3 :   tbl->magic = 0UL;
     120           3 :   return tbl;
     121           3 : }
     122             : 
     123             : void
     124           9 : fd_netdev_tbl_reset( fd_netdev_tbl_join_t * tbl ) {
     125           9 :   tbl->hdr->dev_cnt  = 0;
     126           9 :   tbl->hdr->bond_cnt = 0;
     127        1554 :   for( ulong j=0UL; j<(tbl->hdr->dev_max); j++ ) {
     128        1545 :     tbl->dev_tbl[j] = (fd_netdev_t) {
     129        1545 :       .master_idx    = -1,
     130        1545 :       .slave_tbl_idx = -1
     131        1545 :     };
     132        1545 :   }
     133           9 :   fd_memset( tbl->bond_tbl, 0, sizeof(fd_netdev_bond_t) * tbl->hdr->bond_max );
     134           9 : }
     135             : 
     136             : void
     137             : fd_netdev_tbl_copy( fd_netdev_tbl_join_t *       dst,
     138           0 :                     fd_netdev_tbl_join_t const * src ) {
     139           0 :   ushort dev_max  = dst->hdr->dev_max;
     140           0 :   ushort bond_max = dst->hdr->bond_max;
     141           0 :   for(;;) {
     142           0 :     ulong seq = fd_seqlock_read_try( &src->hdr->seqlock );
     143           0 :     dst->hdr->dev_cnt  = src->hdr->dev_cnt;
     144           0 :     dst->hdr->bond_cnt = src->hdr->bond_cnt;
     145           0 :     fd_memcpy( dst->dev_tbl,  src->dev_tbl,  sizeof(fd_netdev_t)      * dev_max  );
     146           0 :     fd_memcpy( dst->bond_tbl, src->bond_tbl, sizeof(fd_netdev_bond_t) * bond_max );
     147           0 :     if( FD_LIKELY( fd_seqlock_read_test( &src->hdr->seqlock, seq ) ) ) return;
     148           0 :     FD_SPIN_PAUSE();
     149           0 :   }
     150           0 : }
     151             : 
     152             : #if FD_HAS_HOSTED
     153             : 
     154             : #include <errno.h>
     155             : #include <stdio.h>
     156             : #include "../../util/net/fd_eth.h"
     157             : 
     158           6 : #define WRAP_PRINT(file,str) if( FD_UNLIKELY( fputs( (str), (file) )<0 ) ) return errno
     159          12 : #define WRAP_PRINTF(file,...) if( FD_UNLIKELY( fprintf( (file), __VA_ARGS__ )<0 ) ) return errno
     160             : 
     161             : int
     162             : fd_netdev_tbl_fprintf( fd_netdev_tbl_join_t const * tbl,
     163           3 :                        void *                       file_ ) {
     164           3 :   FILE * file = file_;
     165          12 :   for( ulong j=0UL; j<(tbl->hdr->dev_cnt); j++ ) {
     166           9 :     fd_netdev_t const * dev = &tbl->dev_tbl[j];
     167           9 :     if( !dev->oper_status ) continue;
     168           6 :     WRAP_PRINTF( file,
     169           6 :         "%u: %s: mtu %u state (%i-%s)",
     170           6 :         dev->if_idx, dev->name, dev->mtu,
     171           6 :         dev->oper_status, fd_oper_status_cstr( dev->oper_status ) );
     172           6 :     if( dev->slave_tbl_idx>=0 ) {
     173           6 :       WRAP_PRINT( file, " master" );
     174           6 :     }
     175           6 :     WRAP_PRINTF( file,
     176           6 :         "\n    link " FD_ETH_MAC_FMT "\n",
     177           6 :         FD_ETH_MAC_FMT_ARGS( dev->mac_addr ) );
     178           6 :     if( dev->slave_tbl_idx>=0 && tbl->bond_tbl[ dev->slave_tbl_idx ].slave_cnt ) {
     179           0 :       fd_netdev_bond_t * bond = &tbl->bond_tbl[ dev->slave_tbl_idx ];
     180           0 :       WRAP_PRINTF( file, "    slaves (%u):", bond->slave_cnt );
     181           0 :       for( ulong k=0UL; k<(bond->slave_cnt); k++ ) {
     182           0 :         WRAP_PRINTF( file, " %u-%s", bond->slave_idx[k], tbl->dev_tbl[ bond->slave_idx[k] ].name );
     183           0 :       }
     184           0 :       WRAP_PRINT( file, "\n" );
     185           0 :     }
     186           6 :   }
     187           3 :   return 0;
     188           3 : }
     189             : 
     190             : #undef WRAP_PRINT
     191             : #undef WRAP_PRINTF
     192             : 
     193             : #endif /* FD_HAS_HOSTED */
     194             : 
     195             : char const *
     196           6 : fd_oper_status_cstr( uint oper_status ) {
     197           6 :   switch( oper_status ) {
     198           3 :   case FD_OPER_STATUS_UP:               return "up";
     199           3 :   case FD_OPER_STATUS_DOWN:             return "down";
     200           0 :   case FD_OPER_STATUS_TESTING:          return "testing";
     201           0 :   case FD_OPER_STATUS_DORMANT:          return "dormant";
     202           0 :   case FD_OPER_STATUS_NOT_PRESENT:      return "not present";
     203           0 :   case FD_OPER_STATUS_LOWER_LAYER_DOWN: return "lower layer down";
     204           0 :   case FD_OPER_STATUS_UNKNOWN: /* fallthrough */
     205           0 :   default:
     206           0 :     return "unknown";
     207           6 :   }
     208           6 : }

Generated by: LCOV version 1.14