LCOV - code coverage report
Current view: top level - waltz/ip - fd_fib4.h (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 7 13 53.8 %
Date: 2025-03-20 12:08:36 Functions: 1 9 11.1 %

          Line data    Source code
       1             : #ifndef HEADER_fd_src_waltz_ip_fd_fib4_h
       2             : #define HEADER_fd_src_waltz_ip_fd_fib4_h
       3             : 
       4             : /* A fib4 stores IPv4 routes in a query-optimized data structure.
       5             : 
       6             :    fib4 does not scale well to large numbers of routes.  Every route
       7             :    lookup is O(n) where n is the number of routes in the FIB.
       8             : 
       9             :    fib4 only supports a minimal set of features required for end devices
      10             :    to operate.  Packet forwarding is not supported.
      11             : 
      12             :    fib4 supports multi-threaded operation in a x86-TSO like environment.
      13             :    (many reader threads, one writer thread)  Refer to each function for
      14             :    thread safety.
      15             : 
      16             :    A fib4 always has a dummy route at index 0.
      17             : 
      18             :    FIXME: CONSIDER TRIE BASED DATA STRUCTURE
      19             : 
      20             :    Trivia: https://en.wikipedia.org/wiki/Forwarding_information_base */
      21             : 
      22             : #include "../../util/fd_util_base.h"
      23             : 
      24             : #define FD_FIB4_ALIGN (16UL)
      25             : 
      26             : /* FD_FIB4_RTYPE_{...} enumerate route types.
      27             :    These match Linux RTN_UNICAST, etc. */
      28             : 
      29           0 : #define FD_FIB4_RTYPE_UNSPEC    (0) /* invalid */
      30          39 : #define FD_FIB4_RTYPE_UNICAST   (1) /* "normal" path */
      31          54 : #define FD_FIB4_RTYPE_LOCAL     (2) /* address on local host */
      32          78 : #define FD_FIB4_RTYPE_BROADCAST (3) /* reserved for future use */
      33           0 : #define FD_FIB4_RTYPE_MULTICAST (5) /* reserved for future use */
      34           0 : #define FD_FIB4_RTYPE_BLACKHOLE (6) /* drop packet */
      35          39 : #define FD_FIB4_RTYPE_THROW     (9) /* continue in next table */
      36             : 
      37             : /* fd_fib4_t is a local handle to a fib4 object.  Use fd_fib4_{align,
      38             :    footprint,new,delete,join,leave} to construct and join a fib4. */
      39             : 
      40             : struct fd_fib4;
      41             : typedef struct fd_fib4 fd_fib4_t;
      42             : 
      43             : /* fd_fib4_hop_t holds a FIB lookup result (see fd_fib4_lookup) */
      44             : 
      45             : struct __attribute__((aligned(16))) fd_fib4_hop {
      46             :   uint  ip4_gw;   /* gateway address (big endian) */
      47             :   uint  if_idx;   /* output interface index */
      48             :   uint  ip4_src;  /* override source address (big endian). 0 implies unset */
      49             :   uchar rtype;    /* route type (e.g. FD_FIB4_RTYPE_UNICAST) */
      50             :   uchar scope;    /* used to select source address */
      51             :   uchar flags;    /* app-specific flags */
      52             : };
      53             : 
      54           0 : #define FD_FIB4_FLAG_RTA_UNSUPPORTED   ((uchar)0x01U) /* unsupported route attribute */
      55           0 : #define FD_FIB4_FLAG_RTA_PARSE_ERR     ((uchar)0x02U) /* failed to interpret route attribute */
      56           0 : #define FD_FIB4_FLAG_RTYPE_UNSUPPORTED ((uchar)0x03U) /* unsupported route type */
      57             : 
      58             : typedef struct fd_fib4_hop fd_fib4_hop_t;
      59             : 
      60             : FD_PROTOTYPES_BEGIN
      61             : 
      62             : /* Constructor APIs ******************************************************/
      63             : 
      64             : FD_FN_CONST ulong
      65             : fd_fib4_align( void );
      66             : 
      67             : FD_FN_CONST ulong
      68             : fd_fib4_footprint( ulong route_max );
      69             : 
      70             : void *
      71             : fd_fib4_new( void * mem,
      72             :              ulong  route_max );
      73             : 
      74             : fd_fib4_t *
      75             : fd_fib4_join( void * mem );
      76             : 
      77             : void *
      78             : fd_fib4_leave( fd_fib4_t * fib4 );
      79             : 
      80             : void *
      81             : fd_fib4_delete( void * mem );
      82             : 
      83             : /* Write APIs *************************************************************
      84             : 
      85             :    Currently, any updates to a fib4 require a full rewrite (incremental
      86             :    updates are not supported).  During an update, fd_fib4_lookup calls
      87             :    temporarily return a route entry with FD_FIB4_RTYPE_BLACKHOLE, which
      88             :    means outgoing packets get dropped.  (This is preferable to potentially
      89             :    making an incorrect routing decision based on a partial route table.) */
      90             : 
      91             : /* fd_fib4_clear removes all route table entries but the first.  Sets
      92             :    the first route table entry to "throw 0.0.0.0/0 metric ((2<<32)-1)". */
      93             : 
      94             : void
      95             : fd_fib4_clear( fd_fib4_t * fib );
      96             : 
      97             : /* fd_fib4_append attempts to add a new route entry.  If
      98             :    fd_fib4_free_cnt(fib) returned non-zero immediately prior to calling
      99             :    append, then append is guaranteed to succeed.
     100             : 
     101             :    Returns a hop object to be filled by the caller on success.  On
     102             :    failure, returns NULL and logs warning. */
     103             : 
     104             : fd_fib4_hop_t *
     105             : fd_fib4_append( fd_fib4_t * fib,
     106             :                 uint        ip4_dst,
     107             :                 int         prefix,
     108             :                 uint        prio );
     109             : 
     110             : /* Read APIs *************************************************************/
     111             : 
     112             : /* fd_fib4_lookup resolves the next hop for an arbitrary IPv4 address.
     113             :    If route was not found, retval->rtype is set to FD_FIB4_RTYPE_THROW.
     114             : 
     115             :    Thread safe: Multiple threads can use the read API concurrently without
     116             :    affecting each other.  If a write by one thread is in progress, all
     117             :    other threads calling fd_fib4_lookup may briefly see a blackhole route
     118             :    being returned.  (Until of the effects of the write become visible to
     119             :    all CPUs in the system) */
     120             : 
     121             : fd_fib4_hop_t const *
     122             : fd_fib4_lookup( fd_fib4_t const * fib,
     123             :                 fd_fib4_hop_t *   out,
     124             :                 uint              ip4_dst,
     125             :                 ulong             flags );
     126             : 
     127             : /* fd_fib4_hop_or is a helper to chain together multiple FIB lookups. */
     128             : 
     129             : FD_FN_PURE static inline fd_fib4_hop_t const *
     130             : fd_fib4_hop_or( fd_fib4_hop_t const * left,
     131          15 :                 fd_fib4_hop_t const * right ) {
     132          15 :   return left->rtype!=FD_FIB4_RTYPE_THROW ? left : right;
     133          15 : }
     134             : 
     135             : /* fd_fib4_max returns the max number of routes in the table. */
     136             : 
     137             : FD_FN_PURE ulong
     138             : fd_fib4_max( fd_fib4_t const * fib );
     139             : 
     140             : /* fd_fib4_cnt returns the number of routes in the table. */
     141             : 
     142             : FD_FN_PURE ulong
     143             : fd_fib4_cnt( fd_fib4_t const * fib );
     144             : 
     145             : /* fd_fib4_free_cnt returns the number of fd_fib4_append calls that are
     146             :    guaranteed to succeed. */
     147             : 
     148             : ulong
     149             : fd_fib4_free_cnt( fd_fib4_t const * fib );
     150             : 
     151             : #if FD_HAS_HOSTED
     152             : 
     153             : /* fd_fib4_fprintf prints the routing table to the given FILE * pointer (or
     154             :    target equivalent).  Order of routes is undefined but guaranteed to be
     155             :    stable between calls.  Outputs ASCII encoding with LF newlines.  Returns
     156             :    errno on failure and 0 on success. */
     157             : 
     158             : int
     159             : fd_fib4_fprintf( fd_fib4_t const * fib,
     160             :                  void *            file );
     161             : 
     162             : #endif
     163             : 
     164             : FD_PROTOTYPES_END
     165             : 
     166             : #endif /* HEADER_fd_src_waltz_ip_fd_fib4_h */

Generated by: LCOV version 1.14