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