LCOV - code coverage report
Current view: top level - disco/net - fd_net_router.h (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 0 74 0.0 %
Date: 2026-10-22 18:10:43 Functions: 0 4 0.0 %

          Line data    Source code
       1             : #ifndef HEADER_fd_src_disco_net_fd_net_router_h
       2             : #define HEADER_fd_src_disco_net_fd_net_router_h
       3             : 
       4             : /* fd_net_router.h provides an internal API for userland routing. */
       5             : 
       6             : #include "fd_net_tile_private.h"
       7             : #include "../../waltz/ip/fd_fib4.h"
       8             : #include "../../waltz/mib/fd_netdev_tbl.h"
       9             : #include "../../waltz/neigh/fd_neigh4_map.h"
      10             : #include "../netlink/fd_netlink_tile.h" /* neigh4_solicit */
      11             : #include "../../util/net/fd_eth.h"
      12             : #include "../../util/net/fd_ip4.h"
      13             : 
      14             : #include <linux/if_arp.h> /* ARPHRD_LOOPBACK */
      15             : 
      16             : struct fd_net_router {
      17             :   ulong netlnk_out_idx;
      18             :   uint  solicit_ip;
      19             :   uint  solicit_if_idx;
      20             : 
      21             :   /* Route and neighbor tables */
      22             :   fd_fib4_t fib_local[1];
      23             :   fd_fib4_t fib_main[1];
      24             :   fd_neigh4_hmap_t  neigh4[1];
      25             : 
      26             :   /* Netdev table */
      27             :   fd_netdev_tbl_join_t netdev_tbl;    /* local copy in scratch */
      28             :   fd_netdev_tbl_join_t netdev_shared; /* shared seqlock-protected table */
      29             : 
      30             :   uint if_virt;
      31             :   uint bind_address;
      32             :   uint default_address;
      33             : 
      34             :   struct {
      35             :     ulong tx_neigh_fail_cnt;
      36             :   } metrics;
      37             : };
      38             : typedef struct fd_net_router fd_net_router_t;
      39             : 
      40             : FD_PROTOTYPES_BEGIN
      41             : 
      42             : /* fd_net_tx_route resolves the destination interface index, src MAC
      43             :    address, and dst MAC address.  Returns 1 on success, 0 on failure.
      44             :    On success, writes the complete route result to out. */
      45             : 
      46             : static int
      47             : fd_net_tx_route( fd_net_router_t *   ctx,
      48             :                  fd_net_tile_t *     net,
      49             :                  uint                dst_ip,
      50           0 :                  fd_net_tx_route_t * out ) {
      51             : 
      52           0 :   if( FD_UNLIKELY( !out ) ) return 0;
      53           0 :   *out = (fd_net_tx_route_t) {0};
      54             : 
      55             :   /* Route lookup */
      56             : 
      57           0 :   fd_fib4_hop_t hop[2] = {0};
      58           0 :   hop[0] = fd_fib4_lookup( ctx->fib_local, dst_ip, 0UL );
      59           0 :   hop[1] = fd_fib4_lookup( ctx->fib_main,  dst_ip, 0UL );
      60           0 :   fd_fib4_hop_t const * next_hop = fd_fib4_hop_or( hop+0, hop+1 );
      61             : 
      62           0 :   uint rtype   = next_hop->rtype;
      63           0 :   uint if_idx  = next_hop->if_idx;
      64           0 :   uint ip4_src = next_hop->ip4_src;
      65             : 
      66           0 :   if( FD_UNLIKELY( rtype==FD_FIB4_RTYPE_LOCAL ) ) {
      67           0 :     rtype  = FD_FIB4_RTYPE_UNICAST;
      68           0 :     if_idx = 1;
      69           0 :   }
      70             : 
      71           0 :   if( FD_UNLIKELY( rtype!=FD_FIB4_RTYPE_UNICAST ) ) {
      72           0 :     uint const reason = fd_uint_if( rtype==FD_FIB4_RTYPE_THROW,
      73           0 :                                     FD_METRICS_ENUM_PKT_TX_DROP_REASON_V_NO_ROUTE_IDX,
      74           0 :                                     FD_METRICS_ENUM_PKT_TX_DROP_REASON_V_UNSUPPORTED_ROUTE_IDX );
      75           0 :     net->metrics.tx_drop_cnt[       reason ]++;
      76           0 :     return 0;
      77           0 :   }
      78             : 
      79           0 :   fd_netdev_t * netdev = fd_netdev_tbl_query( &ctx->netdev_tbl, if_idx );
      80           0 :   if( !netdev ) {
      81           0 :     net->metrics.tx_drop_cnt[ FD_METRICS_ENUM_PKT_TX_DROP_REASON_V_INTERFACE_MISSING_IDX ]++;
      82           0 :     return 0;
      83           0 :   }
      84             : 
      85           0 :   ip4_src = fd_uint_if( !!ctx->bind_address, ctx->bind_address, ip4_src );
      86           0 :   out->mtu    = netdev->mtu;
      87           0 :   out->src_ip = ip4_src;
      88           0 :   out->if_idx = if_idx;
      89             : 
      90           0 :   if( netdev->dev_type==ARPHRD_LOOPBACK ) {
      91           0 :     memset( out->mac_addrs, 0, sizeof(out->mac_addrs) );
      92           0 :     out->src_ip       = fd_uint_if( !ip4_src, FD_IP4_ADDR( 127,0,0,1 ), ip4_src );
      93           0 :     out->use_loopback = 1U;
      94           0 :     return 1;
      95           0 :   } else if( netdev->dev_type==ARPHRD_IPGRE ) {
      96             :     /* skip MAC addrs lookup for GRE inner dst ip */
      97           0 :     out->gre_outer_src_ip = netdev->gre_src_ip;
      98           0 :     out->gre_outer_dst_ip = netdev->gre_dst_ip;
      99           0 :     out->use_gre = 1U;
     100           0 :     return 1;
     101           0 :   }
     102             : 
     103           0 :   if( FD_UNLIKELY( netdev->dev_type!=ARPHRD_ETHER ) ) {
     104           0 :     net->metrics.tx_drop_cnt[ FD_METRICS_ENUM_PKT_TX_DROP_REASON_V_UNSUPPORTED_INTERFACE_IDX ]++;
     105           0 :     return 0;
     106           0 :   }
     107             : 
     108           0 :   if( FD_UNLIKELY( if_idx!=ctx->if_virt ) ) {
     109           0 :     net->metrics.tx_drop_cnt[ FD_METRICS_ENUM_PKT_TX_DROP_REASON_V_UNSUPPORTED_INTERFACE_IDX ]++;
     110           0 :     return 0;
     111           0 :   }
     112             : 
     113             :   /* Neighbor resolve */
     114           0 :   uint neigh_ip = next_hop->ip4_gw;
     115           0 :   if( !neigh_ip ) neigh_ip = dst_ip;
     116             : 
     117           0 :   fd_neigh4_entry_t neigh[1];
     118           0 :   int neigh_res = fd_neigh4_hmap_query_entry( ctx->neigh4, neigh_ip, neigh );
     119           0 :   if( FD_UNLIKELY( neigh_res!=FD_MAP_SUCCESS ) ) {
     120             :     /* Neighbor not found */
     121           0 :     ctx->solicit_ip     = neigh_ip;
     122           0 :     ctx->solicit_if_idx = if_idx;
     123           0 :     ctx->metrics.tx_neigh_fail_cnt++;
     124           0 :     return 0;
     125           0 :   }
     126           0 :   if( FD_UNLIKELY( neigh->state != FD_NEIGH4_STATE_ACTIVE ) ) {
     127           0 :     ctx->metrics.tx_neigh_fail_cnt++;
     128           0 :     return 0;
     129           0 :   }
     130           0 :   ip4_src = fd_uint_if( !ip4_src, ctx->default_address, ip4_src );
     131           0 :   out->src_ip = ip4_src;
     132           0 :   memcpy( out->mac_addrs+0, neigh->mac_addr,  6 );
     133           0 :   memcpy( out->mac_addrs+6, netdev->mac_addr, 6 );
     134             : 
     135           0 :   return 1;
     136           0 : }
     137             : 
     138             : static inline void
     139             : fd_net_router_solicit( fd_net_router_t *   ctx,
     140           0 :                        fd_stem_context_t * stem ) {
     141           0 :   if( FD_LIKELY( !ctx->solicit_ip ) ) return;
     142             : 
     143           0 :   fd_stem_publish( stem, ctx->netlnk_out_idx, fd_netlink_neigh4_solicit_sig( ctx->solicit_ip, ctx->solicit_if_idx ), 0UL, 0UL, 0UL, 0UL, fd_frag_meta_ts_comp( fd_tickcount() ) );
     144           0 :   ctx->solicit_ip = 0U;
     145           0 : }
     146             : 
     147             : FD_PROTOTYPES_END
     148             : 
     149             : #endif /* HEADER_fd_src_disco_net_fd_net_router_h */

Generated by: LCOV version 1.14