Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fddev netns fixes #4219

Merged
merged 1 commit into from
Feb 13, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 11 additions & 3 deletions src/app/fdctl/config.c
Original file line number Diff line number Diff line change
Expand Up @@ -526,12 +526,20 @@ fdctl_cfg_from_env( int * pargc,
config->is_live_cluster = cluster != FD_CLUSTER_UNKNOWN;

if( FD_UNLIKELY( config->development.netns.enabled ) ) {
/* not currently supporting multihoming on netns */
if( FD_UNLIKELY( strcmp( config->development.netns.interface0, config->tiles.net.interface ) ) )
if( !strcmp( config->tiles.net.interface, "" ) ) {
memcpy( config->tiles.net.interface, config->development.netns.interface0, sizeof(config->tiles.net.interface) );
}

if( !strcmp( config->development.pktgen.fake_dst_ip, "" ) ) {
memcpy( config->development.pktgen.fake_dst_ip, config->development.netns.interface1_addr, sizeof(config->development.netns.interface1_addr) );
}

if( FD_UNLIKELY( strcmp( config->development.netns.interface0, config->tiles.net.interface ) ) ) {
FD_LOG_ERR(( "netns interface and firedancer interface are different. If you are using the "
"[development.netns] functionality to run Firedancer in a network namespace "
"for development, the configuration file must specify that "
"[development.netns.interface0] is the same as [net.interface]" ));
"[development.netns.interface0] is the same as [tiles.net.interface]" ));
}

if( FD_UNLIKELY( !fd_cstr_to_ip4_addr( config->development.netns.interface0_addr, &config->tiles.net.ip_addr ) ) )
FD_LOG_ERR(( "configuration specifies invalid netns IP address `%s`", config->development.netns.interface0_addr ));
Expand Down
4 changes: 2 additions & 2 deletions src/app/fdctl/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -175,10 +175,10 @@ struct fdctl_config {
int enabled;
char interface0 [ 16 ];
char interface0_mac [ 32 ];
char interface0_addr[ 32 ];
char interface0_addr[ 16 ];
char interface1 [ 16 ];
char interface1_mac [ 32 ];
char interface1_addr[ 32 ];
char interface1_addr[ 16 ];
} netns;

struct {
Expand Down
6 changes: 1 addition & 5 deletions src/app/fdctl/netconf.c
Original file line number Diff line number Diff line change
Expand Up @@ -50,11 +50,7 @@ netconf_cmd_fn( args_t * args,
fd_fib4_fprintf( fib4_local, stdout );
fd_fib4_leave( fib4_local );

char if_name[ IF_NAMESIZE ] = "???";
if( FD_UNLIKELY( !if_indextoname( tile->netlink.neigh_if_idx, if_name ) ) ) {
memcpy( if_name, "???", 4 );
}
printf( "\nNEIGHBOR TABLE (%u-%s)\n\n", tile->netlink.neigh_if_idx, if_name );
printf( "\nNEIGHBOR TABLE (%.16s)\n\n", tile->netlink.neigh_if );
fd_neigh4_hmap_t neigh4[1];
FD_TEST( fd_neigh4_hmap_join( neigh4, fd_topo_obj_laddr( topo, tile->netlink.neigh4_obj_id ), fd_topo_obj_laddr( topo, tile->netlink.neigh4_ele_obj_id ) ) );
fd_neigh4_hmap_fprintf( neigh4, stdout );
Expand Down
48 changes: 31 additions & 17 deletions src/app/fdctl/run/run.c
Original file line number Diff line number Diff line change
Expand Up @@ -687,27 +687,29 @@ extern configure_stage_t fd_cfg_stage_ethtool_loopback;
extern configure_stage_t fd_cfg_stage_sysctl;

void
fdctl_check_configure( config_t * const config ) {
fdctl_check_configure( config_t * config ) {
configure_result_t check = fd_cfg_stage_hugetlbfs.check( config );
if( FD_UNLIKELY( check.result!=CONFIGURE_OK ) )
FD_LOG_ERR(( "Huge pages are not configured correctly: %s. You can run `fdctl configure init hugetlbfs` "
"to create the mounts correctly. This must be done after every system restart before running "
"Firedancer.", check.message ));

check = fd_cfg_stage_ethtool_channels.check( config );
if( FD_UNLIKELY( check.result!=CONFIGURE_OK ) )
FD_LOG_ERR(( "Network %s. You can run `fdctl configure init ethtool-channels` to set the number of channels on the "
"network device correctly.", check.message ));

check = fd_cfg_stage_ethtool_gro.check( config );
if( FD_UNLIKELY( check.result!=CONFIGURE_OK ) )
FD_LOG_ERR(( "Network %s. You can run `fdctl configure init ethtool-gro` to disable generic-receive-offload "
"as required.", check.message ));

check = fd_cfg_stage_ethtool_loopback.check( config );
if( FD_UNLIKELY( check.result!=CONFIGURE_OK ) )
FD_LOG_ERR(( "Network %s. You can run `fdctl configure init ethtool-loopback` to disable tx-udp-segmentation "
"on the loopback device.", check.message ));
if( FD_LIKELY( !config->development.netns.enabled ) ) {
check = fd_cfg_stage_ethtool_channels.check( config );
if( FD_UNLIKELY( check.result!=CONFIGURE_OK ) )
FD_LOG_ERR(( "Network %s. You can run `fdctl configure init ethtool-channels` to set the number of channels on the "
"network device correctly.", check.message ));

check = fd_cfg_stage_ethtool_gro.check( config );
if( FD_UNLIKELY( check.result!=CONFIGURE_OK ) )
FD_LOG_ERR(( "Network %s. You can run `fdctl configure init ethtool-gro` to disable generic-receive-offload "
"as required.", check.message ));

check = fd_cfg_stage_ethtool_loopback.check( config );
if( FD_UNLIKELY( check.result!=CONFIGURE_OK ) )
FD_LOG_ERR(( "Network %s. You can run `fdctl configure init ethtool-loopback` to disable tx-udp-segmentation "
"on the loopback device.", check.message ));
}

check = fd_cfg_stage_sysctl.check( config );
if( FD_UNLIKELY( check.result!=CONFIGURE_OK ) )
Expand All @@ -716,8 +718,8 @@ fdctl_check_configure( config_t * const config ) {
}

void
run_firedancer_init( config_t * const config,
int init_workspaces ) {
run_firedancer_init( config_t * config,
int init_workspaces ) {
struct stat st;
int err = stat( config->consensus.identity_path, &st );
if( FD_UNLIKELY( -1==err && errno==ENOENT ) ) FD_LOG_ERR(( "[consensus.identity_path] key does not exist `%s`. You can generate an identity key at this path by running `fdctl keys new identity --config <toml>`", config->consensus.identity_path ));
Expand All @@ -734,6 +736,18 @@ run_firedancer_init( config_t * const config,
initialize_stacks( config );
}

void
fdctl_setup_netns( config_t * config ) {
if( config->development.netns.enabled ) {
enter_network_namespace( config->tiles.net.interface );
close_network_namespace_original_fd();
}

fd_cfg_stage_ethtool_channels.init( config );
fd_cfg_stage_ethtool_gro .init( config );
fd_cfg_stage_ethtool_loopback.init( config );
}

/* The boot sequence is a little bit involved...

A process tree is created that looks like,
Expand Down
3 changes: 3 additions & 0 deletions src/app/fdctl/run/run.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ void
run_firedancer_init( config_t * const config,
int init_workspaces );

void
fdctl_setup_netns( config_t * config );

void
run_firedancer( config_t * const config,
int parent_pipefd,
Expand Down
12 changes: 12 additions & 0 deletions src/app/fdctl/utility.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@
#include <fcntl.h>
#include <sched.h>
#include <dirent.h>
#include <net/if.h> /* IFF_UP */

#include <sys/ioctl.h> /* ioctl(2) */
#include <sys/mman.h> /* for mprotect */
#include <sys/stat.h>
#include <sys/socket.h>
Expand Down Expand Up @@ -40,6 +42,16 @@ enter_network_namespace( const char * interface ) {
FD_LOG_ERR(( "failed to enter network namespace `%s` (%i-%s)", path, errno, fd_io_strerror( errno ) ));
int ret = close( fd );
if( FD_UNLIKELY( ret ) ) FD_LOG_ERR(( "enter_network_namespace %d (%i-%s)", ret, errno, fd_io_strerror( errno ) ));

/* `ip link set dev lo up`
Done via the ioctl API for simplicity. Requires a dummy socket. */
int ifreq_fd = socket( AF_INET, SOCK_DGRAM, 0 );
if( FD_UNLIKELY( ifreq_fd<0 ) ) FD_LOG_ERR(( "socket(AF_INET,SOCK_DGRAM,0) failed (%i-%s)", errno, fd_io_strerror( errno ) ));
struct ifreq ifr = { .ifr_name = "lo" };
if( FD_UNLIKELY( ioctl( ifreq_fd, SIOCGIFFLAGS, &ifr ) ) ) FD_LOG_ERR(( "ioctl(SIOCGIFFLAGS,\"lo\") failed (%i-%s)", errno, fd_io_strerror( errno ) ));
ifr.ifr_flags |= (IFF_UP|IFF_RUNNING);
if( FD_UNLIKELY( ioctl( ifreq_fd, SIOCSIFFLAGS, &ifr ) ) ) FD_LOG_ERR(( "ioctl(SIOCGIFFLAGS,\"lo\",IFF_UP|IFF_RUNNING) failed (%i-%s)", errno, fd_io_strerror( errno ) ));
if( FD_UNLIKELY( close( ifreq_fd ) ) ) FD_LOG_ERR(( "failed to close dummy UDP socket (%i-%s)", errno, fd_io_strerror( errno ) ));
}

void
Expand Down
1 change: 1 addition & 0 deletions src/app/fddev/bench.c
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,7 @@ bench_cmd_fn( args_t * args,
update_config_for_dev( config );

run_firedancer_init( config, 1 );
fdctl_setup_netns( config );

fd_xdp_fds_t fds = fd_topo_install_xdp( &config->topo );
(void)fds;
Expand Down
1 change: 1 addition & 0 deletions src/app/fddev/dev.c
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,7 @@ run_firedancer_threaded( config_t * config , int init_workspaces) {
fd_topo_print_log( 0, &config->topo );

run_firedancer_init( config, init_workspaces );
fdctl_setup_netns( config );

if( FD_UNLIKELY( config->development.debug_tile ) ) {
fd_log_private_shared_lock[ 1 ] = 1;
Expand Down
1 change: 1 addition & 0 deletions src/app/fddev/pktgen.c
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ pktgen_cmd_fn( args_t * args,
/* FIXME this allocates lots of memory unnecessarily */
initialize_workspaces( config );
initialize_stacks( config );
fdctl_setup_netns( config );
(void)fd_topo_install_xdp( &config->topo );;
fd_topo_join_workspaces( &config->topo, FD_SHMEM_JOIN_MODE_READ_WRITE );

Expand Down
9 changes: 7 additions & 2 deletions src/ballet/http/fd_http_server.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include "picohttpparser.h"
#include "fd_sha1.h"
#include "../base64/fd_base64.h"
#include "../../util/net/fd_ip4.h"

#include <stdarg.h>
#include <stdio.h>
Expand Down Expand Up @@ -282,8 +283,12 @@ fd_http_server_listen( fd_http_server_t * http,
.sin_addr.s_addr = address,
};

if( FD_UNLIKELY( -1==bind( sockfd, fd_type_pun( &addr ), sizeof( addr ) ) ) ) FD_LOG_ERR(( "bind failed (%i-%s)", errno, strerror( errno ) ));
if( FD_UNLIKELY( -1==listen( sockfd, (int)http->max_conns ) ) ) FD_LOG_ERR(( "listen failed (%i-%s)", errno, strerror( errno ) ));
if( FD_UNLIKELY( -1==bind( sockfd, fd_type_pun( &addr ), sizeof( addr ) ) ) ) {
FD_LOG_ERR(( "bind(%i,AF_INET," FD_IP4_ADDR_FMT ":%u) failed (%i-%s)",
sockfd, FD_IP4_ADDR_FMT_ARGS( address ), port,
errno, fd_io_strerror( errno ) ));
}
if( FD_UNLIKELY( -1==listen( sockfd, (int)http->max_conns ) ) ) FD_LOG_ERR(( "listen failed (%i-%s)", errno, fd_io_strerror( errno ) ));

http->socket_fd = sockfd;
http->pollfds[ http->max_conns+http->max_ws_conns ].fd = http->socket_fd;
Expand Down
9 changes: 5 additions & 4 deletions src/disco/netlink/fd_netlink_tile.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,6 @@ fd_netlink_topo_create( fd_topo_tile_t * netlink_tile,

/* Configure neighbor hashmap: Open addressed hashmap with 3.0 sparsity
factor and 16 long probe chain */
uint const neigh_if_idx = if_nametoindex( config->tiles.net.interface );
if( FD_UNLIKELY( !neigh_if_idx ) ) FD_LOG_ERR(( "if_nametoindex(%s) failed (%i-%s)", config->tiles.net.interface, errno, fd_io_strerror( errno ) ));
ulong const neigh_ele_max = fd_ulong_pow2_up( 3UL * config->tiles.netlink.max_neighbors );
ulong const neigh_ele_align = alignof(fd_neigh4_entry_t);
ulong const neigh_ele_fp = neigh_ele_max * sizeof(fd_neigh4_entry_t);
Expand All @@ -67,7 +65,7 @@ fd_netlink_topo_create( fd_topo_tile_t * netlink_tile,
netlink_tile->netlink.netdev_dbl_buf_obj_id = netdev_dbl_buf_obj->id;
netlink_tile->netlink.fib4_main_obj_id = fib4_main_obj->id;
netlink_tile->netlink.fib4_local_obj_id = fib4_local_obj->id;
netlink_tile->netlink.neigh_if_idx = neigh_if_idx;
memcpy( netlink_tile->netlink.neigh_if, config->tiles.net.interface, sizeof(netlink_tile->netlink.neigh_if) );
netlink_tile->netlink.neigh4_obj_id = neigh4_obj->id;
netlink_tile->netlink.neigh4_ele_obj_id = neigh4_ele_obj->id;
}
Expand Down Expand Up @@ -135,10 +133,13 @@ privileged_init( fd_topo_t * topo,
FD_LOG_ERR(( "Topology contains more than one netlink tile" ));
}

uint const neigh_if_idx = if_nametoindex( tile->netlink.neigh_if );
if( FD_UNLIKELY( !neigh_if_idx ) ) FD_LOG_ERR(( "if_nametoindex(%.16s) failed (%i-%s)", tile->netlink.neigh_if, errno, fd_io_strerror( errno ) ));

fd_netlink_tile_ctx_t * ctx = fd_topo_obj_laddr( topo, tile->tile_obj_id );
fd_memset( ctx, 0, sizeof(fd_netlink_tile_ctx_t) );
ctx->magic = FD_NETLINK_TILE_CTX_MAGIC;
ctx->neigh4_ifidx = tile->netlink.neigh_if_idx;
ctx->neigh4_ifidx = neigh_if_idx;

if( FD_UNLIKELY( !fd_netlink_init( ctx->nl_monitor, 1000U ) ) ) {
FD_LOG_ERR(( "Failed to connect to rtnetlink" ));
Expand Down
2 changes: 1 addition & 1 deletion src/disco/topo/fd_topo.h
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ typedef struct {
ulong netdev_dbl_buf_obj_id; /* dbl_buf containing netdev_tbl */
ulong fib4_main_obj_id; /* fib4 containing main route table */
ulong fib4_local_obj_id; /* fib4 containing local route table */
uint neigh_if_idx; /* neigh4 interface index */
char neigh_if[ 16 ]; /* neigh4 interface name */
ulong neigh4_obj_id; /* neigh4 hash map header */
ulong neigh4_ele_obj_id; /* neigh4 hash map slots */
} netlink;
Expand Down
5 changes: 3 additions & 2 deletions src/waltz/mib/fd_netdev_netlink.c
Original file line number Diff line number Diff line change
Expand Up @@ -120,13 +120,14 @@ fd_netdev_netlink_load_table( fd_netdev_tbl_join_t * tbl,
switch( rat->rta_type ) {

case IFLA_IFNAME:
if( FD_UNLIKELY( rta_sz==0 || rta_sz>=IFNAMSIZ ) ) {
/* Includes trailing zero */
if( FD_UNLIKELY( rta_sz==0 || rta_sz>IFNAMSIZ ) ) {
FD_LOG_WARNING(( "Error reading interface table: IFLA_IFNAME has unsupported size %lu", rta_sz ));
err = EPROTO;
goto fail;
}
memcpy( netdev->name, rta, rta_sz );
netdev->name[ rta_sz ] = '\0';
netdev->name[ rta_sz-1 ] = '\0';
break;

case IFLA_ADDRESS:
Expand Down
Loading