Line data Source code
1 : /* fd_pktgen_tile floods a net tile with small outgoing packets. 2 : 3 : Each packet is a minimum size Ethernet frame. An invalid 4 : Ethertype is used to avoid leaking the flood out to the Internet. 5 : 6 : Each packet contains a 64 bit sequence number such that each 7 : payload is different. Experiments revealed that some NICs stop 8 : sending if we send the same payload over and over again 9 : (probably protection against a buggy driver melting the network). */ 10 : 11 : #include "../../../../disco/topo/fd_topo.h" 12 : #include "../../../../util/net/fd_eth.h" 13 : 14 : extern uint fd_pktgen_active; 15 : uint fd_pktgen_active = 0U; 16 : 17 : struct fd_pktgen_tile_ctx { 18 : void * out_base; 19 : ulong chunk0; 20 : ulong wmark; 21 : ulong chunk; 22 : ulong tag; 23 : uint fake_dst_ip; 24 : }; 25 : 26 : typedef struct fd_pktgen_tile_ctx fd_pktgen_tile_ctx_t; 27 : 28 : FD_FN_CONST static inline ulong 29 0 : scratch_align( void ) { 30 0 : return alignof(fd_pktgen_tile_ctx_t); 31 0 : } 32 : 33 : FD_FN_PURE static inline ulong 34 0 : scratch_footprint( fd_topo_tile_t const * tile FD_PARAM_UNUSED ) { 35 0 : return sizeof(fd_pktgen_tile_ctx_t); 36 0 : } 37 : 38 : static void 39 : unprivileged_init( fd_topo_t * topo, 40 0 : fd_topo_tile_t * tile ) { 41 0 : fd_pktgen_tile_ctx_t * ctx = fd_topo_obj_laddr( topo, tile->tile_obj_id ); 42 0 : FD_TEST( tile->out_cnt==1UL ); 43 0 : void * out_base = topo->workspaces[ topo->objs[ topo->links[ tile->out_link_id[ 0 ] ].dcache_obj_id ].wksp_id ].wksp; 44 0 : void * out_dcache = topo->links[ tile->out_link_id[ 0 ] ].dcache; 45 0 : ctx->out_base = out_base; 46 0 : ctx->chunk0 = fd_dcache_compact_chunk0( out_base, out_dcache ); 47 0 : ctx->wmark = fd_dcache_compact_wmark( out_base, out_dcache, FD_NET_MTU ); 48 0 : ctx->chunk = ctx->chunk0; 49 0 : ctx->tag = 0UL; 50 0 : ctx->fake_dst_ip = tile->pktgen.fake_dst_ip; 51 : 52 : /* Assume dcache was zero initialized */ 53 0 : } 54 : 55 : static void 56 : before_credit( fd_pktgen_tile_ctx_t * ctx, 57 : fd_stem_context_t * stem, 58 0 : int * charge_busy ) { 59 0 : if( FD_VOLATILE_CONST( fd_pktgen_active )!=1U ) return; 60 : 61 0 : *charge_busy = 1; 62 : 63 : /* Select an arbitrary public IP as the fake destination. The outgoing 64 : packet is not an Internet packet, so it will not reach that 65 : destination. The net tile, however, needs a valid dst IP to select 66 : the dst MAC address. */ 67 0 : ulong sig = fd_disco_netmux_sig( 0U, 0U, ctx->fake_dst_ip, DST_PROTO_OUTGOING, FD_NETMUX_SIG_MIN_HDR_SZ ); 68 : 69 : /* Send an Ethernet frame */ 70 0 : ulong chunk = ctx->chunk; 71 0 : uchar * frame = fd_chunk_to_laddr( ctx->out_base, chunk ); 72 0 : ulong tag = ctx->tag; 73 0 : ulong sz = sizeof(fd_eth_hdr_t) + 46; 74 0 : FD_STORE( ulong, frame+sizeof(fd_eth_hdr_t), tag ); 75 0 : fd_stem_publish( stem, 0UL, sig, chunk, sz, 0UL, 0UL, 0UL ); 76 : 77 : /* Wind up for next iteration */ 78 0 : chunk++; /* Min sz Ethernet frames are exactly FD_CHUNK_SZ */ 79 0 : chunk = fd_ulong_if( chunk>ctx->wmark, ctx->chunk0, chunk ); 80 0 : ctx->tag = tag+1UL; 81 0 : ctx->chunk = chunk; 82 0 : } 83 : 84 0 : #define STEM_BURST (1UL) 85 : 86 0 : #define STEM_CALLBACK_CONTEXT_TYPE fd_pktgen_tile_ctx_t 87 0 : #define STEM_CALLBACK_CONTEXT_ALIGN alignof(fd_pktgen_tile_ctx_t) 88 : 89 0 : #define STEM_CALLBACK_BEFORE_CREDIT before_credit 90 : 91 : #include "../../../../disco/stem/fd_stem.c" 92 : 93 : fd_topo_run_tile_t fd_tile_pktgen = { 94 : .name = "pktgen", 95 : .scratch_align = scratch_align, 96 : .scratch_footprint = scratch_footprint, 97 : .unprivileged_init = unprivileged_init, 98 : .run = stem_run 99 : };