Line data Source code
1 : #ifndef HEADER_fd_src_waltz_mib_fd_netdev_tbl_h 2 : #define HEADER_fd_src_waltz_mib_fd_netdev_tbl_h 3 : 4 : /* fd_netdev_tbl.h provides a network interface table. 5 : The entrypoint of this API is fd_netlink_tbl_t. */ 6 : 7 : #include "fd_seqlock.h" 8 : 9 : /* FD_OPER_STATUS_* give the operational state of a network interface. 10 : See RFC 2863 Section 3.1.14: https://datatracker.ietf.org/doc/html/rfc2863#section-3.1.14 */ 11 : 12 0 : #define FD_OPER_STATUS_INVALID (0) 13 6 : #define FD_OPER_STATUS_UP (1) /* ready to pass packets */ 14 6 : #define FD_OPER_STATUS_DOWN (2) 15 0 : #define FD_OPER_STATUS_TESTING (3) /* in some test mode */ 16 0 : #define FD_OPER_STATUS_UNKNOWN (4) /* status can not be determined */ 17 0 : #define FD_OPER_STATUS_DORMANT (5) 18 0 : #define FD_OPER_STATUS_NOT_PRESENT (6) /* some component is missing */ 19 0 : #define FD_OPER_STATUS_LOWER_LAYER_DOWN (7) /* down due to state of lower-layer interface(s) */ 20 : 21 : /* fd_netdev_t holds basic configuration of a network device. */ 22 : 23 : struct fd_netdev { 24 : ushort mtu; /* Largest layer-3 payload that fits in a packet */ 25 : uchar mac_addr[6]; /* MAC address */ 26 : uint if_idx; /* Interface index */ 27 : short slave_tbl_idx; /* index to bond slave table, -1 if not a bond master */ 28 : int master_idx; /* index of bond master, -1 if not a bond slave */ 29 : char name[16]; /* cstr interface name (max 15 length) */ 30 : uchar oper_status; /* one of FD_OPER_STATUS_{...} */ 31 : ushort dev_type; /* one of ARPHRD_ETHER/_LOOPBACK_/IPGRE*/ 32 : uint gre_dst_ip; 33 : uint gre_src_ip; 34 : }; 35 : 36 : typedef struct fd_netdev fd_netdev_t; 37 : 38 : /* FD_NETDEV_BOND_SLAVE_MAX is the max supported number of bond slaves. */ 39 : 40 : #define FD_NETDEV_BOND_SLAVE_MAX (16) 41 : 42 : /* fd_netdev_bond_t lists active slaves of a bond device. */ 43 : 44 : struct fd_netdev_bond { 45 : uchar slave_cnt; 46 : ushort slave_idx[ FD_NETDEV_BOND_SLAVE_MAX ]; 47 : }; 48 : 49 : typedef struct fd_netdev_bond fd_netdev_bond_t; 50 : 51 : /* fd_netdev_tbl_t provides an interface table. 52 : 53 : This table is optimized for frequent reads and rare writes. It is 54 : generally not thread-safe to modify the table in-place. The only safe 55 : way to sync modifications to other threads is by copying the table in 56 : its entirety. */ 57 : 58 : struct fd_netdev_tbl_private; 59 : typedef struct fd_netdev_tbl_private fd_netdev_tbl_t; 60 : 61 : struct fd_netdev_tbl_hdr { 62 : atomic_ulong seqlock; 63 : ushort dev_max; 64 : ushort bond_max; 65 : ushort dev_cnt; 66 : ushort bond_cnt; 67 : }; 68 : typedef struct fd_netdev_tbl_hdr fd_netdev_tbl_hdr_t; 69 : 70 : struct fd_netdev_tbl_join { 71 : fd_netdev_tbl_hdr_t * hdr; 72 : fd_netdev_t * dev_tbl; 73 : fd_netdev_bond_t * bond_tbl; 74 : }; 75 : typedef struct fd_netdev_tbl_join fd_netdev_tbl_join_t; 76 : 77 9 : #define FD_NETDEV_TBL_MAGIC (0xd5f9ba2710d6bf0aUL) /* random */ 78 : 79 : /* FD_NETDEV_TBL_ALIGN is the return value of fd_netdev_tbl_align() */ 80 : 81 12 : #define FD_NETDEV_TBL_ALIGN (16UL) 82 : 83 : FD_PROTOTYPES_BEGIN 84 : 85 : /* fd_netdev_tbl_{align,footprint} describe a memory region suitable to 86 : back a netdev_tbl with dev_max interfaces and bond_max bond masters. */ 87 : 88 : FD_FN_CONST ulong 89 : fd_netdev_tbl_align( void ); 90 : 91 : FD_FN_CONST ulong 92 : fd_netdev_tbl_footprint( ulong dev_max, 93 : ulong bond_max ); 94 : 95 : /* fd_netdev_tbl_new formats a memory region as an empty netdev_tbl. 96 : Returns shmem on success. On failure returns NULL and logs reason for 97 : failure. */ 98 : 99 : void * 100 : fd_netdev_tbl_new( void * shmem, 101 : ulong dev_max, 102 : ulong bond_max ); 103 : 104 : /* fd_netdev_tbl_join joins a netdev_tbl at shtbl. ljoin points to a 105 : fd_netdev_tbl_join_t[1] to which object information is written to. 106 : Returns ljoin on success. On failure, returns NULL and logs reason for 107 : failure. */ 108 : 109 : fd_netdev_tbl_join_t * 110 : fd_netdev_tbl_join( void * ljoin, 111 : void * shtbl ); 112 : 113 : /* fd_netdev_tbl_leave undoes a fd_netdev_tbl_join. Returns ownership 114 : of the region backing join to the caller. (Warning: This returns ljoin, 115 : not shtbl) */ 116 : 117 : void * 118 : fd_netdev_tbl_leave( fd_netdev_tbl_join_t * join ); 119 : 120 : /* fd_netdev_tbl_delete unformats the memory region backing a netdev_tbl 121 : and returns ownership of the region back to the caller. */ 122 : 123 : void * 124 : fd_netdev_tbl_delete( void * shtbl ); 125 : 126 : /* fd_netdev_tbl_reset resets the table to the state of a newly constructed 127 : empty object (clears all devices and bonds). */ 128 : 129 : void 130 : fd_netdev_tbl_reset( fd_netdev_tbl_join_t * tbl ); 131 : 132 : /* fd_netdev_tbl_query queries the netdev table for a device with idx if_idx. 133 : Returns pointer to the device object if found, otherwise NULL. */ 134 : 135 : static inline fd_netdev_t * 136 : fd_netdev_tbl_query( fd_netdev_tbl_join_t * tbl, 137 39 : uint if_idx ) { 138 39 : fd_netdev_t * dev = tbl->dev_tbl; 139 39 : ulong j; 140 39 : #define UNROLL_FACTOR 8 141 39 : for( j = 0UL; j+UNROLL_FACTOR < tbl->hdr->dev_cnt; j+=UNROLL_FACTOR ) { 142 0 : if( FD_UNLIKELY( dev[j+0].if_idx==if_idx )) return dev+j+0; 143 0 : if( FD_UNLIKELY( dev[j+1].if_idx==if_idx )) return dev+j+1; 144 0 : if( FD_UNLIKELY( dev[j+2].if_idx==if_idx )) return dev+j+2; 145 0 : if( FD_UNLIKELY( dev[j+3].if_idx==if_idx )) return dev+j+3; 146 0 : if( FD_UNLIKELY( dev[j+4].if_idx==if_idx )) return dev+j+4; 147 0 : if( FD_UNLIKELY( dev[j+5].if_idx==if_idx )) return dev+j+5; 148 0 : if( FD_UNLIKELY( dev[j+6].if_idx==if_idx )) return dev+j+6; 149 0 : if( FD_UNLIKELY( dev[j+7].if_idx==if_idx )) return dev+j+7; 150 0 : } 151 39 : #undef UNROLL_FACTOR 152 : 153 108 : for( ; j<tbl->hdr->dev_cnt; j++ ) { 154 105 : if( dev[j].if_idx==if_idx ) return dev+j; 155 105 : } 156 3 : return NULL; 157 39 : } 158 : 159 : /* fd_netdev_tbl_copy copies *src to *dst, while doing seqlock checks 160 : on src. Assumes dst is writable (seq-lock held). Assumes dst and 161 : src have identical {dev,bond}_max limits. Blocking (spins until copy 162 : completes). */ 163 : 164 : void 165 : fd_netdev_tbl_copy( fd_netdev_tbl_join_t * dst, 166 : fd_netdev_tbl_join_t const * src ); 167 : 168 : #if FD_HAS_HOSTED 169 : 170 : /* fd_netdev_tbl_fprintf prints the interface table to the given FILE * 171 : pointer (or target equivalent). Outputs ASCII encoding with LF 172 : newlines. Returns errno on failure and 0 on success. */ 173 : 174 : int 175 : fd_netdev_tbl_fprintf( fd_netdev_tbl_join_t const * tbl, 176 : void * file ); 177 : 178 : #endif /* FD_HAS_HOSTED */ 179 : 180 : FD_PROTOTYPES_END 181 : 182 : char const * 183 : fd_oper_status_cstr( uint oper_status ); 184 : 185 : #endif /* HEADER_fd_src_waltz_mib_fd_netdev_tbl_h */