LCOV - code coverage report
Current view: top level - disco/net - fd_net_tile_topo.c (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 0 131 0.0 %
Date: 2025-07-01 05:00:49 Functions: 0 8 0.0 %

          Line data    Source code
       1             : /* Topology support routines for the net tile */
       2             : 
       3             : #include "fd_net_tile.h"
       4             : #include "../topo/fd_topob.h"
       5             : #include "../netlink/fd_netlink_tile.h"
       6             : #include "../../app/shared/fd_config.h" /* FIXME layering violation */
       7             : #include "../../util/pod/fd_pod_format.h"
       8             : 
       9             : #include <net/if.h>
      10             : 
      11             : static void
      12             : setup_xdp_tile( fd_topo_t *             topo,
      13             :                 ulong                   i,
      14             :                 fd_topo_tile_t *        netlink_tile,
      15             :                 ulong const *           tile_to_cpu,
      16           0 :                 fd_config_net_t const * net_cfg ) {
      17           0 :   fd_topo_tile_t * tile = fd_topob_tile( topo, "net", "net", "metric_in", tile_to_cpu[ topo->tile_cnt ], 0, 0 );
      18           0 :   fd_topob_link( topo, "net_netlnk", "net_netlnk", 128UL, 0UL, 0UL );
      19           0 :   fd_topob_tile_in(  topo, "netlnk", 0UL, "metric_in", "net_netlnk", i, FD_TOPOB_UNRELIABLE, FD_TOPOB_POLLED );
      20           0 :   fd_topob_tile_out( topo, "net",    i,                "net_netlnk", i );
      21           0 :   fd_netlink_topo_join( topo, netlink_tile, tile );
      22             : 
      23           0 :   fd_topo_obj_t * umem_obj = fd_topob_obj( topo, "dcache", "net_umem" );
      24           0 :   fd_topob_tile_uses( topo, tile, umem_obj, FD_SHMEM_JOIN_MODE_READ_WRITE );
      25           0 :   fd_pod_insertf_ulong( topo->props, umem_obj->id, "net.%lu.umem", i );
      26             : 
      27           0 :   FD_STATIC_ASSERT( sizeof(tile->xdp.interface)==IF_NAMESIZE, str_bounds );
      28           0 :   fd_cstr_fini( fd_cstr_append_cstr_safe( fd_cstr_init( tile->xdp.interface ), net_cfg->interface, IF_NAMESIZE-1 ) );
      29           0 :   tile->net.bind_address = net_cfg->bind_address_parsed;
      30             : 
      31           0 :   tile->xdp.tx_flush_timeout_ns = (long)net_cfg->xdp.flush_timeout_micros * 1000L;
      32           0 :   tile->xdp.xdp_rx_queue_size = net_cfg->xdp.xdp_rx_queue_size;
      33           0 :   tile->xdp.xdp_tx_queue_size = net_cfg->xdp.xdp_tx_queue_size;
      34           0 :   tile->xdp.zero_copy         = net_cfg->xdp.xdp_zero_copy;
      35           0 :   fd_memset( tile->xdp.xdp_mode, 0, 4 );
      36           0 :   fd_memcpy( tile->xdp.xdp_mode, net_cfg->xdp.xdp_mode, strnlen( net_cfg->xdp.xdp_mode, 3 ) );  /* GCC complains about strncpy */
      37             : 
      38           0 :   tile->xdp.net.umem_dcache_obj_id= umem_obj->id;
      39           0 :   tile->xdp.netdev_dbl_buf_obj_id = netlink_tile->netlink.netdev_dbl_buf_obj_id;
      40           0 :   tile->xdp.fib4_main_obj_id      = netlink_tile->netlink.fib4_main_obj_id;
      41           0 :   tile->xdp.fib4_local_obj_id     = netlink_tile->netlink.fib4_local_obj_id;
      42           0 :   tile->xdp.neigh4_obj_id         = netlink_tile->netlink.neigh4_obj_id;
      43           0 :   tile->xdp.neigh4_ele_obj_id     = netlink_tile->netlink.neigh4_ele_obj_id;
      44             : 
      45             :   /* Allocate free ring */
      46             : 
      47           0 :   tile->xdp.free_ring_depth = tile->xdp.xdp_tx_queue_size;
      48           0 :   if( i==0 ) {
      49             :     /* Allocate additional frames for loopback */
      50           0 :     tile->xdp.free_ring_depth += 16384UL;
      51           0 :   }
      52           0 : }
      53             : 
      54             : static void
      55             : setup_sock_tile( fd_topo_t *             topo,
      56             :                  ulong const *           tile_to_cpu,
      57           0 :                  fd_config_net_t const * net_cfg ) {
      58           0 :   fd_topo_tile_t * tile = fd_topob_tile( topo, "sock", "sock", "metric_in", tile_to_cpu[ topo->tile_cnt ], 0, 0 );
      59           0 :   tile->sock.net.bind_address = net_cfg->bind_address_parsed;
      60             : 
      61           0 :   if( FD_UNLIKELY( net_cfg->socket.receive_buffer_size>INT_MAX ) ) FD_LOG_ERR(( "invalid [net.socket.receive_buffer_size]" ));
      62           0 :   if( FD_UNLIKELY( net_cfg->socket.send_buffer_size   >INT_MAX ) ) FD_LOG_ERR(( "invalid [net.socket.send_buffer_size]" ));
      63           0 :   tile->sock.so_rcvbuf = (int)net_cfg->socket.receive_buffer_size;
      64           0 :   tile->sock.so_sndbuf = (int)net_cfg->socket.send_buffer_size   ;
      65           0 : }
      66             : 
      67             : void
      68             : fd_topos_net_tiles( fd_topo_t *             topo,
      69             :                     ulong                   net_tile_cnt,
      70             :                     fd_config_net_t const * net_cfg,
      71             :                     ulong                   netlnk_max_routes,
      72             :                     ulong                   netlnk_max_neighbors,
      73           0 :                     ulong const             tile_to_cpu[ FD_TILE_MAX ] ) {
      74             :   /* net_umem: Packet buffers */
      75           0 :   fd_topob_wksp( topo, "net_umem" );
      76             : 
      77             :   /* Create workspaces */
      78             : 
      79           0 :   if( 0==strcmp( net_cfg->provider, "xdp" ) ) {
      80             : 
      81             :     /* net: private working memory of the net tiles */
      82           0 :     fd_topob_wksp( topo, "net" );
      83             :     /* netlnk: private working memory of the netlnk tile */
      84           0 :     fd_topob_wksp( topo, "netlnk" );
      85             :     /* netbase: shared network config (config plane) */
      86           0 :     fd_topob_wksp( topo, "netbase" );
      87             :     /* net_netlnk: net->netlnk ARP requests */
      88           0 :     fd_topob_wksp( topo, "net_netlnk" );
      89             : 
      90           0 :     fd_topo_tile_t * netlink_tile = fd_topob_tile( topo, "netlnk", "netlnk", "metric_in", tile_to_cpu[ topo->tile_cnt ], 0, 0 );
      91           0 :     fd_netlink_topo_create( netlink_tile, topo, netlnk_max_routes, netlnk_max_neighbors, net_cfg->interface );
      92             : 
      93           0 :     for( ulong i=0UL; i<net_tile_cnt; i++ ) {
      94           0 :       setup_xdp_tile( topo, i, netlink_tile, tile_to_cpu, net_cfg );
      95           0 :     }
      96             : 
      97           0 :   } else if( 0==strcmp( net_cfg->provider, "socket" ) ) {
      98             : 
      99             :     /* sock: private working memory of the sock tiles */
     100           0 :     fd_topob_wksp( topo, "sock" );
     101             : 
     102           0 :     for( ulong i=0UL; i<net_tile_cnt; i++ ) {
     103           0 :       setup_sock_tile( topo, tile_to_cpu, net_cfg );
     104           0 :     }
     105             : 
     106           0 :   } else {
     107           0 :     FD_LOG_ERR(( "invalid `net.provider`" ));
     108           0 :   }
     109           0 : }
     110             : 
     111             : static int
     112           0 : topo_is_xdp( fd_topo_t * topo ) {
     113             :   /* FIXME hacky */
     114           0 :   for( ulong j=0UL; j<(topo->tile_cnt); j++ ) {
     115           0 :     if( 0==strcmp( topo->tiles[ j ].name, "net" ) ) {
     116           0 :       return 1;
     117           0 :     }
     118           0 :   }
     119           0 :   return 0;
     120           0 : }
     121             : 
     122             : static void
     123             : add_xdp_rx_link( fd_topo_t *  topo,
     124             :                  char const * link_name,
     125             :                  ulong        net_kind_id,
     126           0 :                  ulong        depth ) {
     127           0 :   if( FD_UNLIKELY( !topo || !link_name  ) ) FD_LOG_ERR(( "NULL args" ));
     128           0 :   if( FD_UNLIKELY( strlen( link_name )>=sizeof(topo->links[ topo->link_cnt ].name ) ) ) FD_LOG_ERR(( "link name too long: %s", link_name ));
     129           0 :   if( FD_UNLIKELY( topo->link_cnt>=FD_TOPO_MAX_LINKS ) ) FD_LOG_ERR(( "too many links" ));
     130             : 
     131           0 :   ulong kind_id = 0UL;
     132           0 :   for( ulong i=0UL; i<topo->link_cnt; i++ ) {
     133           0 :     if( !strcmp( topo->links[ i ].name, link_name ) ) kind_id++;
     134           0 :   }
     135             : 
     136           0 :   fd_topo_link_t * link = &topo->links[ topo->link_cnt ];
     137           0 :   strncpy( link->name, link_name, sizeof(link->name) );
     138           0 :   link->id       = topo->link_cnt;
     139           0 :   link->kind_id  = kind_id;
     140           0 :   link->depth    = depth;
     141           0 :   link->mtu      = FD_NET_MTU;
     142           0 :   link->burst    = 0UL;
     143             : 
     144           0 :   fd_topo_obj_t * obj = fd_topob_obj( topo, "mcache", "net_umem" );
     145           0 :   link->mcache_obj_id = obj->id;
     146           0 :   FD_TEST( fd_pod_insertf_ulong( topo->props, depth, "obj.%lu.depth", obj->id ) );
     147             : 
     148           0 :   link->dcache_obj_id = fd_pod_queryf_ulong( topo->props, ULONG_MAX, "net.%lu.umem", net_kind_id );
     149           0 :   if( FD_UNLIKELY( link->dcache_obj_id==ULONG_MAX ) ) FD_LOG_ERR(( "umem dcache not found for net %lu", net_kind_id ));
     150             : 
     151           0 :   topo->link_cnt++;
     152           0 : }
     153             : 
     154             : void
     155             : fd_topos_net_rx_link( fd_topo_t *  topo,
     156             :                       char const * link_name,
     157             :                       ulong        net_kind_id,
     158           0 :                       ulong        depth ) {
     159           0 :   if( topo_is_xdp( topo ) ) {
     160           0 :     add_xdp_rx_link( topo, link_name, net_kind_id, depth );
     161           0 :     fd_topob_tile_out( topo, "net", net_kind_id, link_name, net_kind_id );
     162           0 :   } else {
     163           0 :     fd_topob_link( topo, link_name, "net_umem", depth, FD_NET_MTU, 64 );
     164           0 :     fd_topob_tile_out( topo, "sock", net_kind_id, link_name, net_kind_id );
     165           0 :   }
     166           0 : }
     167             : 
     168             : void
     169             : fd_topos_tile_in_net( fd_topo_t *  topo,
     170             :                       char const * fseq_wksp,
     171             :                       char const * link_name,
     172             :                       ulong        link_kind_id,
     173             :                       int          reliable,
     174           0 :                       int          polled ) {
     175           0 :   for( ulong j=0UL; j<(topo->tile_cnt); j++ ) {
     176           0 :     if( 0==strcmp( topo->tiles[ j ].name, "net"  ) ||
     177           0 :         0==strcmp( topo->tiles[ j ].name, "sock" ) ) {
     178           0 :       fd_topob_tile_in( topo, topo->tiles[ j ].name, topo->tiles[ j ].kind_id, fseq_wksp, link_name, link_kind_id, reliable, polled );
     179           0 :     }
     180           0 :   }
     181           0 : }
     182             : 
     183             : void
     184             : fd_topos_net_tile_finish( fd_topo_t * topo,
     185           0 :                           ulong       net_kind_id ) {
     186           0 :   if( !topo_is_xdp( topo ) ) return;
     187             : 
     188           0 :   fd_topo_tile_t * net_tile = &topo->tiles[ fd_topo_find_tile( topo, "net", net_kind_id ) ];
     189             : 
     190           0 :   ulong rx_depth = net_tile->xdp.xdp_rx_queue_size;
     191           0 :   ulong tx_depth = net_tile->xdp.xdp_tx_queue_size;
     192           0 :   rx_depth += (rx_depth/2UL);
     193           0 :   tx_depth += (tx_depth/2UL);
     194             : 
     195           0 :   if( net_kind_id==0 ) {
     196             :     /* Double it for loopback XSK */
     197           0 :     rx_depth *= 2UL;
     198           0 :     tx_depth *= 2UL;
     199           0 :   }
     200             : 
     201           0 :   ulong cum_frame_cnt = rx_depth + tx_depth;
     202             : 
     203             :   /* Count up the depth of all RX mcaches */
     204             : 
     205           0 :   for( ulong j=0UL; j<(net_tile->out_cnt); j++ ) {
     206           0 :     ulong link_id       = net_tile->out_link_id[ j ];
     207           0 :     ulong mcache_obj_id = topo->links[ link_id ].mcache_obj_id;
     208           0 :     ulong depth = fd_pod_queryf_ulong( topo->props, ULONG_MAX, "obj.%lu.depth", mcache_obj_id );
     209           0 :     if( FD_UNLIKELY( depth==ULONG_MAX ) ) FD_LOG_ERR(( "Didn't find depth for mcache %s", topo->links[ link_id ].name ));
     210           0 :     cum_frame_cnt += depth + 1UL;
     211           0 :   }
     212             : 
     213             :   /* Create a dcache object */
     214             : 
     215           0 :   ulong umem_obj_id = fd_pod_queryf_ulong( topo->props, ULONG_MAX, "net.%lu.umem", net_kind_id );
     216           0 :   FD_TEST( umem_obj_id!=ULONG_MAX );
     217             : 
     218           0 :   FD_TEST( net_tile->net.umem_dcache_obj_id > 0 );
     219           0 :   fd_pod_insertf_ulong( topo->props, cum_frame_cnt, "obj.%lu.depth", umem_obj_id );
     220           0 :   fd_pod_insertf_ulong( topo->props, 2UL,           "obj.%lu.burst", umem_obj_id ); /* 4096 byte padding */
     221           0 :   fd_pod_insertf_ulong( topo->props, 2048UL,        "obj.%lu.mtu",   umem_obj_id );
     222           0 : }

Generated by: LCOV version 1.14