LCOV - code coverage report
Current view: top level - waltz/ip - fd_netlink.h (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 12 12 100.0 %
Date: 2024-11-13 11:58:15 Functions: 0 0 -

          Line data    Source code
       1             : #ifndef HEADER_fd_src_waltz_fd_netlink_h
       2             : #define HEADER_fd_src_waltz_fd_netlink_h
       3             : 
       4             : #include "fd_ip_enum.h"
       5             : #include "../../util/fd_util.h"
       6             : #include <linux/neighbour.h>
       7             : 
       8             : 
       9             : #define FD_ARP_STATES(x,...) \
      10             :     x( NUD_NONE       , __VA_ARGS__ ) \
      11             :     x( NUD_NOARP      , __VA_ARGS__ ) \
      12             :     x( NUD_PERMANENT  , __VA_ARGS__ ) \
      13             :     x( NUD_DELAY      , __VA_ARGS__ ) \
      14             :     x( NUD_STALE      , __VA_ARGS__ ) \
      15             :     x( NUD_REACHABLE  , __VA_ARGS__ )
      16             : 
      17             : #define FD_ARP_STATE_MATCH_BEGIN(value,state) \
      18             :     ( (state) == value ? #value :
      19             : 
      20             : #define FD_ARP_STATE_MATCH_END(value,state) \
      21             :     )
      22             : 
      23             : #define FD_ARP_STATE_STRING(state)                \
      24             :     FD_ARP_STATES(FD_ARP_STATE_MATCH_BEGIN,state) \
      25             :     "UNKNOWN"                                     \
      26             :     FD_ARP_STATES(FD_ARP_STATE_MATCH_END,state)
      27             : 
      28             : /* Defined the buffer space used in netlink calls
      29             :    We are not expecting many routing entries or ARP cache entries */
      30             : #define FD_NL_BUF_SZ (1UL<<16UL)
      31             : 
      32             : struct fd_nl {
      33             :   int   fd;   /* netlink socket */
      34             :   uint  seq;  /* netlink sequence number */
      35             :   int   init; /* bool are we initialized? */
      36             : };
      37             : typedef struct fd_nl fd_nl_t;
      38             : 
      39             : 
      40             : struct fd_nl_route_entry {
      41             :   uint dst_ip_addr;    /* destination subnet */
      42             :   uint dst_netmask;    /* destination netmask  */
      43             :   uint dst_netmask_sz; /* size of netmask in bits */
      44             : 
      45             :   uint nh_ip_addr;     /* next hop ip address - AKA gateway */
      46             :                        /* zero if no next hop */
      47             : 
      48             :   /* IPv4 address - source ip addr */
      49             :   uint src_ip_addr;
      50             : 
      51             :   /* output interface index */
      52             :   uint oif;
      53             : 
      54             :   /* flags
      55             :      FD_NL_RT_FLAGS_USED        Entry contains data
      56             :      FD_NL_RT_FLAGS_DST_IP_ADDR Entry contains an ip address
      57             :      FD_NL_RT_FLAGS_DST_NETMASK Entry contains a netmask
      58             :      FD_NL_RT_FLAGS_NH_IP_ADDR  Entry contains an ip address
      59             :      FD_NL_RT_FLAGS_SRC_IP_ADDR Entry contains a (preferred) source ip address
      60             :      FD_NL_RT_FLAGS_OIF         Entry contains an output interface index
      61             :      FD_NL_RT_FLAGS_UNSUPPORTED Entry contains an unsupported feature */
      62             :   uint flags;
      63        1506 : # define  FD_NL_RT_FLAGS_USED        (1U << 0U)
      64          75 : # define  FD_NL_RT_FLAGS_UNSUPPORTED (1U << 1U)
      65          39 : # define  FD_NL_RT_FLAGS_DST_IP_ADDR (1U << 2U)
      66          39 : # define  FD_NL_RT_FLAGS_DST_NETMASK (1U << 3U)
      67          36 : # define  FD_NL_RT_FLAGS_NH_IP_ADDR  (1U << 4U)
      68           9 : # define  FD_NL_RT_FLAGS_SRC_IP_ADDR (1U << 5U)
      69          75 : # define  FD_NL_RT_FLAGS_OIF         (1U << 6U)
      70             : };
      71             : typedef struct fd_nl_route_entry fd_nl_route_entry_t;
      72             : 
      73             : 
      74             : /* ARP entries for IPv4 and Ethernet */
      75             : struct fd_nl_arp_entry {
      76             :   uint  dst_ip_addr;
      77             :   uchar mac_addr[6];
      78             :   uint  ifindex;
      79             : 
      80             :   /* states, as in linux/netlink.h */
      81             :   uint  state;
      82             : 
      83             :   /* Flags
      84             :      FD_NL_ARP_FLAGS_USED        Entry contains data
      85             :      FD_NL_ARP_FLAGS_IP_ADDR     Entry contains an ip address
      86             :      FD_NL_ARP_FLAGS_MAC_ADDR    Entry contains a MAC address
      87             :      FD_NL_ARP_FLAGS_IFINDEX     Entry contains an interface index
      88             :      FD_NL_ARP_FLAGS_UNSUPPORTED Entry contains an unsupported feature */
      89             :   uint flags;
      90         615 : # define  FD_NL_ARP_FLAGS_USED        (1U << 0U)
      91          48 : # define  FD_NL_ARP_FLAGS_UNSUPPORTED (1U << 1U)
      92          21 : # define  FD_NL_ARP_FLAGS_IP_ADDR     (1U << 2U)
      93          21 : # define  FD_NL_ARP_FLAGS_MAC_ADDR    (1U << 3U)
      94          24 : # define  FD_NL_ARP_FLAGS_IFINDEX     (1U << 4U)
      95             : };
      96             : typedef struct fd_nl_arp_entry fd_nl_arp_entry_t;
      97             : 
      98             : 
      99             : FD_PROTOTYPES_BEGIN
     100             : 
     101             : 
     102             : /* Creates and configures a socket for netlink
     103             : 
     104             :    used by fd_nl_init */
     105             : int
     106             : fd_nl_create_socket( void );
     107             : 
     108             : 
     109             : /* Closes a netlink socket */
     110             : void
     111             : fd_nl_close_socket( int fd );
     112             : 
     113             : 
     114             : /* Initializes fd_nl_t
     115             : 
     116             :    seq should be set to some reasonably random value */
     117             : int
     118             : fd_nl_init( fd_nl_t * nl, uint seq );
     119             : 
     120             : 
     121             : /* finalizes fd_nl_t, closes socket */
     122             : void
     123             : fd_nl_fini( fd_nl_t * nl );
     124             : 
     125             : 
     126             : /* Loads the routing table referred to as route_table
     127             :    from the kernel using the netlink socket defined in
     128             :    nl
     129             :    Unused entries are zeroed out
     130             : 
     131             :    Args
     132             :      nl               The netlink instance
     133             :      route_table      A pointer to the array of fd_nl_route_entry_t objects
     134             :                         to load with data
     135             :      route_table_cap  The number of entries in the route_table array
     136             : 
     137             :    Return
     138             :      -1               If a transient error occurred
     139             :      count            The number of entries filled with data */
     140             : long
     141             : fd_nl_load_route_table( fd_nl_t *             nl,
     142             :                         fd_nl_route_entry_t * route_table,
     143             :                         ulong                 route_table_cap );
     144             : 
     145             : 
     146             : /* Queries the routing table for a suitable routing entry
     147             :    for the given ip_addr
     148             : 
     149             :    Returns a pointer to the entry, or NULL if none is found */
     150             : fd_nl_route_entry_t *
     151             : fd_nl_route_query( fd_nl_route_entry_t * route_table, ulong route_table_sz, uint ip_addr );
     152             : 
     153             : 
     154             : /* loads the specified arp_table with entries from the kernel
     155             :    using the netlink socket defined in nl
     156             :    Unused entries are zeroed out
     157             : 
     158             :    Args
     159             :      nl               The netlink instance
     160             :      arp_table        A pointer to the array of fd_nl_arp_entry_t objects
     161             :                         to load with data
     162             :      arp_table_cap    The number of entries in the arp_table array
     163             : 
     164             :    Return
     165             :      FD_IP_ERROR      If a permanent error occurred
     166             :      FD_IP_RETRY      If a transient error occurred
     167             :      count            The number of entries filled with data */
     168             : long
     169             : fd_nl_load_arp_table( fd_nl_t *           nl,
     170             :                       fd_nl_arp_entry_t * arp_table,
     171             :                       ulong               arp_table_cap );
     172             : 
     173             : 
     174             : /* Queries the specified arp_table for an entry matching ip_addr
     175             : 
     176             :    NOTE This is currently O(N), which is fine for small tables
     177             :    but we might want to use a hashmap for larger tables */
     178             : fd_nl_arp_entry_t *
     179             : fd_nl_arp_query( fd_nl_arp_entry_t * arp_table,
     180             :                  ulong               arp_table_sz,
     181             :                  uint                ip_addr );
     182             : 
     183             : 
     184             : /* Prepares the ARP cache for receiving a new ARP entry
     185             :    May reload the supplied arp_table
     186             : 
     187             :    Should be called prior to sending an ARP request
     188             : 
     189             :    The kernel ignores unsolicited ARP responses, so this function
     190             :    allows our ARP requests to update the kernel ARP table
     191             : 
     192             :    It creates or updates an entry depending on the current state
     193             :    If there is no entry, it creates one in state NONE
     194             :    Otherwise, it moves NONE to INCOMPLETE and moves DELAY to PROBE
     195             :    This should give the kernel what it needs to handle the rest of
     196             :    the transitions correctly
     197             : 
     198             :    reachable indicates that we have received packets from the address
     199             :    in question. It's only a positive indicator, and its absence implies
     200             :    nothing about reachability
     201             : 
     202             :    return values:
     203             :      FD_IP_SUCCESS   Call successful, nothing to do
     204             :      FD_IP_PROBE     Call successful, caller should send an ARP probe
     205             :      FD_IP_RETRY     Call successful, caller should try this call again soon
     206             :                        or immediately
     207             :      FD_IP_ERROR     Call unsuccessful */
     208             : int
     209             : fd_nl_update_arp_table( fd_nl_t *           nl,
     210             :                         fd_nl_arp_entry_t * arp_table,
     211             :                         ulong               arp_table_cap,
     212             :                         uint                ip_addr,
     213             :                         uint                ifindex );
     214             : 
     215             : 
     216             : FD_PROTOTYPES_END
     217             : 
     218             : #endif

Generated by: LCOV version 1.14