Line data Source code
1 : #ifndef HEADER_fd_src_disco_net_fd_net_tile_h 2 : #define HEADER_fd_src_disco_net_fd_net_tile_h 3 : 4 : /* fd_net_tile.h contains APIs for providing XDP networking to a 5 : Firedancer topology using the 'net' tile. */ 6 : 7 : #include "../fd_disco_base.h" 8 : #include "../../tango/dcache/fd_dcache.h" 9 : #include "../../waltz/xdp/fd_xdp1.h" 10 : 11 : struct fd_topo; 12 : typedef struct fd_topo fd_topo_t; 13 : 14 : /* Helpers for consumers of net tile RX packets */ 15 : 16 : struct fd_net_rx_bounds { 17 : ulong base; /* base address of wksp containing dcache */ 18 : ulong pkt_lo; /* lowest permitted pointer to packet payload */ 19 : ulong pkt_wmark; /* highest " */ 20 : }; 21 : 22 : typedef struct fd_net_rx_bounds fd_net_rx_bounds_t; 23 : 24 : /* FD_NET_BOND_SLAVE_MAX is the hardcoded max number of slave devices 25 : per network bonding setup. */ 26 : 27 0 : #define FD_NET_BOND_SLAVE_MAX 16U 28 : 29 : FD_PROTOTYPES_BEGIN 30 : 31 : /* fd_net_rx_bounds_init initializes a bounds checker for RX packets 32 : produced by the net tile. dcache is a local join to a dcache that 33 : will carry packet payloads. */ 34 : 35 : FD_FN_UNUSED static void 36 : fd_net_rx_bounds_init( fd_net_rx_bounds_t * bounds, 37 0 : void * dcache ) { 38 0 : bounds->base = (ulong)fd_wksp_containing( dcache ); 39 0 : bounds->pkt_lo = (ulong)dcache; 40 0 : bounds->pkt_wmark = bounds->pkt_lo + fd_dcache_data_sz( dcache ) - FD_NET_MTU; 41 0 : if( FD_UNLIKELY( !bounds->base ) ) FD_LOG_ERR(( "Failed to find wksp containing dcache" )); 42 0 : } 43 : 44 : /* fd_net_rx_translate_frag helps net tile consumers locate packet 45 : paylads. bounds is a net_rx_bounds object for the net tile that the 46 : frag was received from. chunk, ctl, sz are frag_meta parameters. 47 : 48 : Returns a pointer in the local address space to the first byte of an 49 : incoming packet. Terminates the application if the given {chunk,ctl} 50 : params would produce an out of bounds buffer. */ 51 : 52 : FD_FN_UNUSED static void const * 53 : fd_net_rx_translate_frag( fd_net_rx_bounds_t const * bounds, 54 : ulong chunk, 55 : ulong ctl, 56 0 : ulong sz ) { 57 0 : ulong p = ((ulong)bounds->base + (chunk<<FD_CHUNK_LG_SZ) + ctl); 58 0 : if( FD_UNLIKELY( !( (p >= bounds->pkt_lo ) & 59 0 : (p <= bounds->pkt_wmark) & 60 0 : (sz <= FD_NET_MTU ) ) ) ) { 61 0 : FD_LOG_ERR(( "frag %p (chunk=%lu ctl=%lu sz=%lu) is not in bounds [%p:%p]", 62 0 : (void *)p, chunk, ctl, sz, 63 0 : (void *)bounds->pkt_lo, (void *)bounds->pkt_wmark )); 64 0 : } 65 0 : return (void const *)p; 66 0 : } 67 : 68 : FD_PROTOTYPES_END 69 : 70 : /* Topology APIs */ 71 : 72 : FD_PROTOTYPES_BEGIN 73 : 74 : /* fd_topos_net_tiles appends the net and netlnk tiles to the 75 : topology. These tiles provide fast XDP networking. */ 76 : 77 : /* FIXME layering violation */ 78 : struct fd_config_net; 79 : typedef struct fd_config_net fd_config_net_t; 80 : 81 : void 82 : fd_topos_net_tiles( fd_topo_t * topo, 83 : ulong net_tile_cnt, 84 : fd_config_net_t const * net_config, 85 : ulong netlnk_max_routes, 86 : ulong netlnk_max_peer_routes, 87 : ulong netlnk_max_neighbors, 88 : ulong const tile_to_cpu[ FD_TILE_MAX ] ); 89 : 90 : /* fd_topos_net_rx_link is like fd_topob_link, but for net->app tile 91 : packet RX links. */ 92 : 93 : void 94 : fd_topos_net_rx_link( fd_topo_t * topo, 95 : char const * link_name, 96 : ulong net_kind_id, 97 : ulong depth ); 98 : 99 : /* fd_topob_tile_in_net registers a net TX link with all net tiles. */ 100 : 101 : void 102 : fd_topos_tile_in_net( fd_topo_t * topo, 103 : char const * fseq_wksp, 104 : char const * link_name, 105 : ulong link_kind_id, 106 : int reliable, 107 : int polled ); 108 : 109 : /* This should be called *after* all app<->net tile links have been 110 : created. Should be called once per net tile. */ 111 : 112 : void 113 : fd_topos_net_tile_finish( fd_topo_t * topo, 114 : ulong net_kind_id ); 115 : 116 : #if defined(__linux__) 117 : 118 : /* fd_topo_install_xdp installs XDP programs to all network devices used 119 : by the topology. This creates a number of file descriptors which 120 : will be returned into the fds array. On entry *fds_cnt is the array 121 : size of fds. On exit, *fds_cnt is the number of fd array entries 122 : used. Closing these fds will undo XDP program installation. 123 : bind_addr is an optional IPv4 address to used for filtering by dst 124 : IP. If dry_run is set, does not actually install XDP config, but 125 : just returns file descriptors where installs would have occurred. */ 126 : 127 : void 128 : fd_topo_install_xdp( fd_topo_t const * topo, 129 : fd_xdp_fds_t * fds, 130 : uint * fds_cnt, 131 : uint bind_addr, 132 : int dry_run ); 133 : 134 : /* FD_TOPO_XDP_FDS_MAX is the max length of the fd_xdp_fds_t array for 135 : an arbitrary supported topology. (Number of bond slave devices plus 136 : loopback) */ 137 : 138 0 : #define FD_TOPO_XDP_FDS_MAX (FD_NET_BOND_SLAVE_MAX+1) 139 : 140 : /* fd_topo_install_xdp_simple is a convenience wrapper of the above. */ 141 : 142 : FD_FN_UNUSED static void 143 : fd_topo_install_xdp_simple( fd_topo_t const * topo, 144 0 : uint bind_addr ) { 145 0 : fd_xdp_fds_t fds[ FD_TOPO_XDP_FDS_MAX ]; 146 0 : uint fds_cnt = FD_TOPO_XDP_FDS_MAX; 147 0 : fd_topo_install_xdp( topo, fds, &fds_cnt, bind_addr, 0 ); 148 0 : } 149 : 150 : #endif /* defined(__linux__) */ 151 : 152 : FD_PROTOTYPES_END 153 : 154 : #endif /* HEADER_fd_src_disco_net_fd_net_tile_h */