LCOV - code coverage report
Current view: top level - waltz/mib - fd_netdev_tbl.c (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 109 146 74.7 %
Date: 2026-09-17 04:28:31 Functions: 10 10 100.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         168 : fd_netdev_tbl_align( void ) {
      13         168 :   return FD_NETDEV_TBL_ALIGN;
      14         168 : }
      15             : 
      16             : FD_FN_CONST ulong
      17             : fd_netdev_tbl_footprint( ulong dev_max,
      18          63 :                          ulong bond_max ) {
      19          63 :   if( FD_UNLIKELY( dev_max ==0UL || dev_max >USHORT_MAX ) ) return 0UL;
      20          63 :   if( FD_UNLIKELY( bond_max==0UL || bond_max>USHORT_MAX ) ) return 0UL;
      21          63 :   return FD_LAYOUT_FINI( FD_LAYOUT_APPEND( FD_LAYOUT_APPEND( FD_LAYOUT_APPEND( FD_LAYOUT_INIT, \
      22          63 :       alignof(fd_netdev_tbl_t),  sizeof(fd_netdev_tbl_t)             ),   \
      23          63 :       alignof(fd_netdev_t),      sizeof(fd_netdev_t)      * dev_max  ),   \
      24          63 :       alignof(fd_netdev_bond_t), sizeof(fd_netdev_bond_t) * bond_max ),   \
      25          63 :       FD_NETDEV_TBL_ALIGN );
      26          63 : }
      27             : 
      28             : void *
      29             : fd_netdev_tbl_new( void * shmem,
      30             :                    ulong  dev_max,
      31          36 :                    ulong  bond_max ) {
      32             : 
      33          36 :   if( FD_UNLIKELY( !shmem ) ) {
      34           0 :     FD_LOG_WARNING(( "NULL shmem" ));
      35           0 :     return NULL;
      36           0 :   }
      37             : 
      38          36 :   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          36 :   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          36 :   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          36 :   FD_SCRATCH_ALLOC_INIT( l, shmem );
      54          36 :   fd_netdev_tbl_t *  tbl  = FD_SCRATCH_ALLOC_APPEND( l, alignof(fd_netdev_tbl_t),  sizeof(fd_netdev_tbl_t) );
      55          36 :   fd_netdev_t *      dev  = FD_SCRATCH_ALLOC_APPEND( l, alignof(fd_netdev_t),      sizeof(fd_netdev_t)      * dev_max  );
      56          36 :   fd_netdev_bond_t * bond = FD_SCRATCH_ALLOC_APPEND( l, alignof(fd_netdev_bond_t), sizeof(fd_netdev_bond_t) * bond_max );
      57          36 :   FD_SCRATCH_ALLOC_FINI( l, FD_NETDEV_TBL_ALIGN );
      58             : 
      59          36 :   *tbl = (fd_netdev_tbl_t) {
      60          36 :     .magic    = FD_NETDEV_TBL_MAGIC,
      61          36 :     .dev_off  = (ulong)dev  - (ulong)tbl,
      62          36 :     .bond_off = (ulong)bond - (ulong)tbl,
      63          36 :     .hdr = {
      64          36 :       .dev_max  = (ushort)dev_max,
      65          36 :       .bond_max = (ushort)bond_max,
      66          36 :       .dev_cnt  = 0,
      67          36 :       .bond_cnt = 0,
      68          36 :     }
      69          36 :   };
      70             : 
      71          36 :   fd_netdev_tbl_join_t join[1];
      72          36 :   fd_netdev_tbl_join( join, shmem );
      73          36 :   fd_netdev_tbl_reset( join );
      74          36 :   fd_netdev_tbl_leave( join );
      75             : 
      76          36 :   return tbl;
      77          36 : }
      78             : 
      79             : fd_netdev_tbl_join_t *
      80             : fd_netdev_tbl_join( void * ljoin,
      81          84 :                     void * shtbl ) {
      82             : 
      83          84 :   if( FD_UNLIKELY( !shtbl ) ) {
      84           0 :     FD_LOG_WARNING(( "NULL shtbl" ));
      85           0 :     return NULL;
      86           0 :   }
      87             : 
      88          84 :   fd_netdev_tbl_join_t * join = ljoin;
      89          84 :   fd_netdev_tbl_t *      tbl  = shtbl;
      90             : 
      91          84 :   if( FD_UNLIKELY( tbl->magic!=FD_NETDEV_TBL_MAGIC ) ) {
      92           0 :     FD_LOG_WARNING(( "bad magic" ));
      93           0 :     return NULL;
      94           0 :   }
      95             : 
      96          84 :   *join = (fd_netdev_tbl_join_t) {
      97          84 :     .hdr      = &tbl->hdr,
      98          84 :     .dev_tbl  = (fd_netdev_t      *)( (ulong)tbl + tbl->dev_off  ),
      99          84 :     .bond_tbl = (fd_netdev_bond_t *)( (ulong)tbl + tbl->bond_off ),
     100          84 :   };
     101             : 
     102          84 :   return join;
     103          84 : }
     104             : 
     105             : void *
     106          39 : fd_netdev_tbl_leave( fd_netdev_tbl_join_t * join ) {
     107          39 :   return join;
     108          39 : }
     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          39 : fd_netdev_tbl_reset( fd_netdev_tbl_join_t * tbl ) {
     125          39 :   tbl->hdr->dev_cnt  = 0;
     126          39 :   tbl->hdr->bond_cnt = 0;
     127        9264 :   for( ulong j=0UL; j<(tbl->hdr->dev_max); j++ ) {
     128        9225 :     tbl->dev_tbl[j] = (fd_netdev_t) {
     129        9225 :       .master_idx    = -1,
     130        9225 :       .slave_tbl_idx = -1
     131        9225 :     };
     132        9225 :   }
     133          39 :   fd_memset( tbl->bond_tbl, 0, sizeof(fd_netdev_bond_t) * tbl->hdr->bond_max );
     134          39 : }
     135             : 
     136             : void
     137             : fd_netdev_tbl_copy( fd_netdev_tbl_join_t *       dst,
     138          12 :                     fd_netdev_tbl_join_t const * src ) {
     139          12 :   ushort dev_max  = dst->hdr->dev_max;
     140          12 :   ushort bond_max = dst->hdr->bond_max;
     141          12 :   for(;;) {
     142          12 :     ulong seq = fd_seqlock_read_try( &src->hdr->seqlock );
     143          12 :     dst->hdr->dev_cnt  = src->hdr->dev_cnt;
     144          12 :     dst->hdr->bond_cnt = src->hdr->bond_cnt;
     145          12 :     fd_memcpy( dst->dev_tbl,  src->dev_tbl,  sizeof(fd_netdev_t)      * dev_max  );
     146          12 :     fd_memcpy( dst->bond_tbl, src->bond_tbl, sizeof(fd_netdev_bond_t) * bond_max );
     147          12 :     if( FD_LIKELY( fd_seqlock_read_test( &src->hdr->seqlock, seq ) ) ) return;
     148           0 :     FD_SPIN_PAUSE();
     149           0 :   }
     150          12 : }
     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