Skip to content

Commit

Permalink
Add ipv6 address support for initial communication.
Browse files Browse the repository at this point in the history
Currenty initial negotiation performed via ipv4 which is not suitable
for modern ipv6 only topology.
This patch allow to specify which address family to use, default
behaviour not changed.

New option:  --ipv6-addr

Usage example:
./ib_write_bw -d mlx5_0 --ipv6-addr
./ib_write_bw -d mlx5_0 --ipv6-addr 2a02:6b8:c0e:97f:0:441d:9fbd:3f1e

signed-off-by: Dmitry Monakhov <[email protected]>
Signed-off-by: Hassan Khadour <[email protected]>
  • Loading branch information
HassanKhadour committed Jul 2, 2023
1 parent 7d00c4b commit 5a218cd
Show file tree
Hide file tree
Showing 6 changed files with 75 additions and 21 deletions.
4 changes: 4 additions & 0 deletions man/perftest.1
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,10 @@ many different options and modes.
Use IPv6 GID. Default is IPv4.
Not relevant for RawEth.
.TP
.B --ipv6-addr=<IPv6>
Use IPv6 address for parameters negotiation. Default is IPv4.
Not relevant for RawEth.
.TP
.B --bind_source_ip
Source IP of the interface used for connection establishment. By default taken from routing table.
Not relevant for RawEth.
Expand Down
50 changes: 30 additions & 20 deletions src/perftest_communication.c
Original file line number Diff line number Diff line change
Expand Up @@ -669,7 +669,7 @@ static int ethernet_client_connect(struct perftest_comm *comm)

int sockfd = -1;
memset(&hints, 0, sizeof hints);
hints.ai_family = AF_INET;
hints.ai_family = comm->rdma_params->ai_family;
hints.ai_socktype = SOCK_STREAM;

if (comm->rdma_params->has_source_ip) {
Expand Down Expand Up @@ -726,7 +726,7 @@ static int ethernet_server_connect(struct perftest_comm *comm)

memset(&hints, 0, sizeof hints);
hints.ai_flags = AI_PASSIVE;
hints.ai_family = AF_INET;
hints.ai_family = comm->rdma_params->ai_family;
hints.ai_socktype = SOCK_STREAM;

if (check_add_port(&service,comm->rdma_params->port,src_ip,&hints,&res))
Expand All @@ -736,6 +736,9 @@ static int ethernet_server_connect(struct perftest_comm *comm)
}

for (t = res; t; t = t->ai_next) {
if (t->ai_family != comm->rdma_params->ai_family)
continue;

sockfd = socket(t->ai_family, t->ai_socktype, t->ai_protocol);

if (sockfd >= 0) {
Expand Down Expand Up @@ -906,29 +909,30 @@ int rdma_client_connect(struct pingpong_context *ctx,struct perftest_parameters
{
char *service;
int temp,num_of_retry= NUM_OF_RETRIES;
struct sockaddr_in sin, source_sin;
struct sockaddr_storage source_sin;
struct sockaddr *sin;
struct sockaddr *source_ptr = NULL;
struct addrinfo *res;
struct rdma_cm_event *event;
struct rdma_conn_param conn_param;
struct addrinfo hints;

memset(&hints, 0, sizeof hints);
hints.ai_family = AF_INET;
hints.ai_family = user_param->ai_family;
hints.ai_socktype = SOCK_STREAM;

if (check_add_port(&service,user_param->port,user_param->servername,&hints,&res)) {
fprintf(stderr, "Problem in resolving basic address and port\n");
return FAILURE;
}

if (res->ai_family != PF_INET) {
if (res->ai_family != user_param->ai_family) {
freeaddrinfo(res);
return FAILURE;
}
memcpy(&sin, res->ai_addr, sizeof(sin));
freeaddrinfo(res);
sin.sin_port = htons((unsigned short)user_param->port);

sin = res->ai_addr;
sockaddr_set_port(sin, (unsigned short)user_param->port);

if (user_param->has_source_ip) {
if (check_add_port(&service, 0x0, user_param->source_ip, &hints, &res))
Expand All @@ -940,7 +944,6 @@ int rdma_client_connect(struct pingpong_context *ctx,struct perftest_parameters
//coverity[deref_after_free]
memcpy(&source_sin, res->ai_addr, sizeof(source_sin));
source_ptr = (struct sockaddr *)&source_sin;
freeaddrinfo(res);
}
while (1)
{
Expand All @@ -950,12 +953,14 @@ int rdma_client_connect(struct pingpong_context *ctx,struct perftest_parameters
return FAILURE;
}

if (rdma_resolve_addr(ctx->cm_id, source_ptr, (struct sockaddr *)&sin, 2000)) {
if (rdma_resolve_addr(ctx->cm_id, source_ptr, sin, 2000)) {
freeaddrinfo(res);
fprintf(stderr, "rdma_resolve_addr failed\n");
return FAILURE;
}

if (rdma_get_cm_event(ctx->cm_channel,&event)) {
freeaddrinfo(res);
fprintf(stderr, "rdma_get_cm_events failed\n");
return FAILURE;
}
Expand All @@ -969,6 +974,7 @@ int rdma_client_connect(struct pingpong_context *ctx,struct perftest_parameters

if (event->event != RDMA_CM_EVENT_ADDR_RESOLVED) {
fprintf(stderr, "unexpected CM event %d\n",event->event);
freeaddrinfo(res);
rdma_ack_cm_event(event);
return FAILURE;
}
Expand All @@ -977,6 +983,8 @@ int rdma_client_connect(struct pingpong_context *ctx,struct perftest_parameters
break;
}

freeaddrinfo(res);

if (user_param->tos != DEF_TOS) {

if (rdma_set_option(ctx->cm_id,RDMA_OPTION_ID,RDMA_OPTION_ID_TOS,&user_param->tos,sizeof(uint8_t))) {
Expand Down Expand Up @@ -1124,35 +1132,36 @@ int rdma_server_connect(struct pingpong_context *ctx,
struct rdma_conn_param conn_param;
struct addrinfo hints;
char *service;
struct sockaddr_in sin;
struct sockaddr *sin;
char* src_ip = user_param->has_source_ip ? user_param->source_ip : NULL;

memset(&hints, 0, sizeof hints);
hints.ai_flags = AI_PASSIVE;
hints.ai_family = AF_INET;
hints.ai_family = user_param->ai_family;
hints.ai_socktype = SOCK_STREAM;

memset(&sin, 0x0, sizeof(sin));

if (check_add_port(&service,user_param->port,src_ip,&hints,&res))
{
fprintf(stderr, "Problem in resolving basic address and port\n");
return FAILURE;
}

if (res->ai_family != PF_INET) {
if (res->ai_family != user_param->ai_family) {
freeaddrinfo(res);
return FAILURE;
}
memcpy(&sin, res->ai_addr, sizeof(sin));
sin.sin_port = htons((unsigned short)user_param->port);
freeaddrinfo(res);

if (rdma_bind_addr(ctx->cm_id_control,(struct sockaddr *)&sin)) {
sin = res->ai_addr;
sockaddr_set_port(sin, (unsigned short)user_param->port);

if (rdma_bind_addr(ctx->cm_id_control, sin)) {
freeaddrinfo(res);
fprintf(stderr," rdma_bind_addr failed\n");
return 1;
}

freeaddrinfo(res);

if (rdma_listen(ctx->cm_id_control, user_param->num_of_qps)) {
fprintf(stderr, "rdma_listen failed\n");
return 1;
Expand Down Expand Up @@ -1243,6 +1252,7 @@ int create_comm_struct(struct perftest_comm *comm,
memset(comm->rdma_params, 0, sizeof(struct perftest_parameters));

comm->rdma_params->port = user_param->port;
comm->rdma_params->ai_family = user_param->ai_family;
comm->rdma_params->sockfd = -1;
comm->rdma_params->gid_index = user_param->gid_index;
comm->rdma_params->gid_index2 = user_param->gid_index2;
Expand Down Expand Up @@ -2034,7 +2044,7 @@ int rdma_cm_get_rdma_address(struct perftest_parameters *user_param,
char port[6] = "", error_message[ERROR_MSG_SIZE] = "";

sprintf(port, "%d", user_param->port);
hints->ai_family = AF_INET;
hints->ai_family = user_param->ai_family;
// if we have servername specified, it is a client, we should use server name
// if it is not specified, we should use explicit source_ip if possible
if ((NULL != user_param->servername) || (!user_param->has_source_ip)) {
Expand Down
9 changes: 9 additions & 0 deletions src/perftest_parameters.c
Original file line number Diff line number Diff line change
Expand Up @@ -461,6 +461,8 @@ static void usage(const char *argv0, VerbType verb, TestType tst, int connection
if (connection_type != RawEth) {
printf(" --ipv6 ");
printf(" Use IPv6 GID. Default is IPv4\n");
printf(" --ipv6-addr=<IPv6> ");
printf(" Use IPv6 address for parameters negotiation. Default is IPv4\n");
}

// please note it is a different source_ip from raw_ethernet case
Expand Down Expand Up @@ -816,6 +818,7 @@ static void init_perftest_params(struct perftest_parameters *user_param)
user_param->retry_count = DEF_RETRY_COUNT;
user_param->dont_xchg_versions = 0;
user_param->ipv6 = 0;
user_param->ai_family = AF_INET;
user_param->report_per_port = 0;
user_param->use_odp = 0;
user_param->use_hugepages = 0;
Expand Down Expand Up @@ -2175,6 +2178,7 @@ int parser(struct perftest_parameters *user_param,char *argv[], int argc)
static int mmap_file_flag = 0;
static int mmap_offset_flag = 0;
static int ipv6_flag = 0;
static int ipv6_addr_flag = 0;
static int raw_ipv6_flag = 0;
static int report_per_port_flag = 0;
static int odp_flag = 0;
Expand Down Expand Up @@ -2326,6 +2330,7 @@ int parser(struct perftest_parameters *user_param,char *argv[], int argc)
{ .name = "mmap", .has_arg = 1, .flag = &mmap_file_flag, .val = 1},
{ .name = "mmap-offset", .has_arg = 1, .flag = &mmap_offset_flag, .val = 1},
{ .name = "ipv6", .has_arg = 0, .flag = &ipv6_flag, .val = 1},
{ .name = "ipv6-addr", .has_arg = 0, .flag = &ipv6_addr_flag, .val = 1},
#ifdef HAVE_IPV6
{ .name = "raw_ipv6", .has_arg = 0, .flag = &raw_ipv6_flag, .val = 1},
#endif
Expand Down Expand Up @@ -3047,6 +3052,10 @@ int parser(struct perftest_parameters *user_param,char *argv[], int argc)
user_param->ipv6 = 1;
}

if (ipv6_addr_flag) {
user_param->ai_family = AF_INET6;
}

if (raw_ipv6_flag) {
if (user_param->is_new_raw_eth_param) {
if (user_param->is_server_ip) {
Expand Down
1 change: 1 addition & 0 deletions src/perftest_parameters.h
Original file line number Diff line number Diff line change
Expand Up @@ -602,6 +602,7 @@ struct perftest_parameters {
int dont_xchg_versions;
int ipv6;
int raw_ipv6;
int ai_family;
int report_per_port;
int use_odp;
int use_hugepages;
Expand Down
19 changes: 18 additions & 1 deletion src/perftest_resources.c
Original file line number Diff line number Diff line change
Expand Up @@ -831,13 +831,30 @@ int check_add_port(char **service,int port,
free(*service);

if (number < 0) {
fprintf(stderr, "%s for %s:%d\n", gai_strerror(number), servername, port);
fprintf(stderr, "%s for ai_family: %x service: %s port: %d\n",
gai_strerror(number), hints->ai_family, servername, port);
return FAILURE;
}

return SUCCESS;
}

/******************************************************************************
*
******************************************************************************/
int sockaddr_set_port(struct sockaddr *sin,int port)
{
switch (sin->sa_family) {
case AF_INET: ((struct sockaddr_in*) sin)->sin_port = htons(port);
break;
case AF_INET6: ((struct sockaddr_in6*) sin)->sin6_port = htons(port);
break;
default:
fprintf(stderr, "ai_family: %x is not yet supported\n", sin->sa_family);
return FAILURE;
}
return SUCCESS;
}
/******************************************************************************
*
******************************************************************************/
Expand Down
13 changes: 13 additions & 0 deletions src/perftest_resources.h
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,19 @@ int check_add_port(char **service,int port,
struct addrinfo *hints,
struct addrinfo **res);

/* sockaddr_set_port
*
* Description : Initialize port for given sockaddr structure
*
* Parameters :
* service - an empty char** to contain the service name.
* port - The selected port on which the server will listen.
* sin - sockaddr params for the connection.
*
* Return Value : SUCCESS, FAILURE.
*/
int sockaddr_set_port(struct sockaddr *sin,int port);

/* ctx_find_dev
*
* Description : Returns the device corresponding to ib_devname
Expand Down

0 comments on commit 5a218cd

Please sign in to comment.