Skip to content

Commit 5a218cd

Browse files
committed
Add ipv6 address support for initial communication.
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]>
1 parent 7d00c4b commit 5a218cd

File tree

6 files changed

+75
-21
lines changed

6 files changed

+75
-21
lines changed

man/perftest.1

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,10 @@ many different options and modes.
268268
Use IPv6 GID. Default is IPv4.
269269
Not relevant for RawEth.
270270
.TP
271+
.B --ipv6-addr=<IPv6>
272+
Use IPv6 address for parameters negotiation. Default is IPv4.
273+
Not relevant for RawEth.
274+
.TP
271275
.B --bind_source_ip
272276
Source IP of the interface used for connection establishment. By default taken from routing table.
273277
Not relevant for RawEth.

src/perftest_communication.c

Lines changed: 30 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -669,7 +669,7 @@ static int ethernet_client_connect(struct perftest_comm *comm)
669669

670670
int sockfd = -1;
671671
memset(&hints, 0, sizeof hints);
672-
hints.ai_family = AF_INET;
672+
hints.ai_family = comm->rdma_params->ai_family;
673673
hints.ai_socktype = SOCK_STREAM;
674674

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

727727
memset(&hints, 0, sizeof hints);
728728
hints.ai_flags = AI_PASSIVE;
729-
hints.ai_family = AF_INET;
729+
hints.ai_family = comm->rdma_params->ai_family;
730730
hints.ai_socktype = SOCK_STREAM;
731731

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

738738
for (t = res; t; t = t->ai_next) {
739+
if (t->ai_family != comm->rdma_params->ai_family)
740+
continue;
741+
739742
sockfd = socket(t->ai_family, t->ai_socktype, t->ai_protocol);
740743

741744
if (sockfd >= 0) {
@@ -906,29 +909,30 @@ int rdma_client_connect(struct pingpong_context *ctx,struct perftest_parameters
906909
{
907910
char *service;
908911
int temp,num_of_retry= NUM_OF_RETRIES;
909-
struct sockaddr_in sin, source_sin;
912+
struct sockaddr_storage source_sin;
913+
struct sockaddr *sin;
910914
struct sockaddr *source_ptr = NULL;
911915
struct addrinfo *res;
912916
struct rdma_cm_event *event;
913917
struct rdma_conn_param conn_param;
914918
struct addrinfo hints;
915919

916920
memset(&hints, 0, sizeof hints);
917-
hints.ai_family = AF_INET;
921+
hints.ai_family = user_param->ai_family;
918922
hints.ai_socktype = SOCK_STREAM;
919923

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

925-
if (res->ai_family != PF_INET) {
929+
if (res->ai_family != user_param->ai_family) {
926930
freeaddrinfo(res);
927931
return FAILURE;
928932
}
929-
memcpy(&sin, res->ai_addr, sizeof(sin));
930-
freeaddrinfo(res);
931-
sin.sin_port = htons((unsigned short)user_param->port);
933+
934+
sin = res->ai_addr;
935+
sockaddr_set_port(sin, (unsigned short)user_param->port);
932936

933937
if (user_param->has_source_ip) {
934938
if (check_add_port(&service, 0x0, user_param->source_ip, &hints, &res))
@@ -940,7 +944,6 @@ int rdma_client_connect(struct pingpong_context *ctx,struct perftest_parameters
940944
//coverity[deref_after_free]
941945
memcpy(&source_sin, res->ai_addr, sizeof(source_sin));
942946
source_ptr = (struct sockaddr *)&source_sin;
943-
freeaddrinfo(res);
944947
}
945948
while (1)
946949
{
@@ -950,12 +953,14 @@ int rdma_client_connect(struct pingpong_context *ctx,struct perftest_parameters
950953
return FAILURE;
951954
}
952955

953-
if (rdma_resolve_addr(ctx->cm_id, source_ptr, (struct sockaddr *)&sin, 2000)) {
956+
if (rdma_resolve_addr(ctx->cm_id, source_ptr, sin, 2000)) {
957+
freeaddrinfo(res);
954958
fprintf(stderr, "rdma_resolve_addr failed\n");
955959
return FAILURE;
956960
}
957961

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

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

986+
freeaddrinfo(res);
987+
980988
if (user_param->tos != DEF_TOS) {
981989

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

11301138
memset(&hints, 0, sizeof hints);
11311139
hints.ai_flags = AI_PASSIVE;
1132-
hints.ai_family = AF_INET;
1140+
hints.ai_family = user_param->ai_family;
11331141
hints.ai_socktype = SOCK_STREAM;
11341142

1135-
memset(&sin, 0x0, sizeof(sin));
1136-
11371143
if (check_add_port(&service,user_param->port,src_ip,&hints,&res))
11381144
{
11391145
fprintf(stderr, "Problem in resolving basic address and port\n");
11401146
return FAILURE;
11411147
}
11421148

1143-
if (res->ai_family != PF_INET) {
1149+
if (res->ai_family != user_param->ai_family) {
11441150
freeaddrinfo(res);
11451151
return FAILURE;
11461152
}
1147-
memcpy(&sin, res->ai_addr, sizeof(sin));
1148-
sin.sin_port = htons((unsigned short)user_param->port);
1149-
freeaddrinfo(res);
11501153

1151-
if (rdma_bind_addr(ctx->cm_id_control,(struct sockaddr *)&sin)) {
1154+
sin = res->ai_addr;
1155+
sockaddr_set_port(sin, (unsigned short)user_param->port);
1156+
1157+
if (rdma_bind_addr(ctx->cm_id_control, sin)) {
1158+
freeaddrinfo(res);
11521159
fprintf(stderr," rdma_bind_addr failed\n");
11531160
return 1;
11541161
}
11551162

1163+
freeaddrinfo(res);
1164+
11561165
if (rdma_listen(ctx->cm_id_control, user_param->num_of_qps)) {
11571166
fprintf(stderr, "rdma_listen failed\n");
11581167
return 1;
@@ -1243,6 +1252,7 @@ int create_comm_struct(struct perftest_comm *comm,
12431252
memset(comm->rdma_params, 0, sizeof(struct perftest_parameters));
12441253

12451254
comm->rdma_params->port = user_param->port;
1255+
comm->rdma_params->ai_family = user_param->ai_family;
12461256
comm->rdma_params->sockfd = -1;
12471257
comm->rdma_params->gid_index = user_param->gid_index;
12481258
comm->rdma_params->gid_index2 = user_param->gid_index2;
@@ -2034,7 +2044,7 @@ int rdma_cm_get_rdma_address(struct perftest_parameters *user_param,
20342044
char port[6] = "", error_message[ERROR_MSG_SIZE] = "";
20352045

20362046
sprintf(port, "%d", user_param->port);
2037-
hints->ai_family = AF_INET;
2047+
hints->ai_family = user_param->ai_family;
20382048
// if we have servername specified, it is a client, we should use server name
20392049
// if it is not specified, we should use explicit source_ip if possible
20402050
if ((NULL != user_param->servername) || (!user_param->has_source_ip)) {

src/perftest_parameters.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -461,6 +461,8 @@ static void usage(const char *argv0, VerbType verb, TestType tst, int connection
461461
if (connection_type != RawEth) {
462462
printf(" --ipv6 ");
463463
printf(" Use IPv6 GID. Default is IPv4\n");
464+
printf(" --ipv6-addr=<IPv6> ");
465+
printf(" Use IPv6 address for parameters negotiation. Default is IPv4\n");
464466
}
465467

466468
// please note it is a different source_ip from raw_ethernet case
@@ -816,6 +818,7 @@ static void init_perftest_params(struct perftest_parameters *user_param)
816818
user_param->retry_count = DEF_RETRY_COUNT;
817819
user_param->dont_xchg_versions = 0;
818820
user_param->ipv6 = 0;
821+
user_param->ai_family = AF_INET;
819822
user_param->report_per_port = 0;
820823
user_param->use_odp = 0;
821824
user_param->use_hugepages = 0;
@@ -2175,6 +2178,7 @@ int parser(struct perftest_parameters *user_param,char *argv[], int argc)
21752178
static int mmap_file_flag = 0;
21762179
static int mmap_offset_flag = 0;
21772180
static int ipv6_flag = 0;
2181+
static int ipv6_addr_flag = 0;
21782182
static int raw_ipv6_flag = 0;
21792183
static int report_per_port_flag = 0;
21802184
static int odp_flag = 0;
@@ -2326,6 +2330,7 @@ int parser(struct perftest_parameters *user_param,char *argv[], int argc)
23262330
{ .name = "mmap", .has_arg = 1, .flag = &mmap_file_flag, .val = 1},
23272331
{ .name = "mmap-offset", .has_arg = 1, .flag = &mmap_offset_flag, .val = 1},
23282332
{ .name = "ipv6", .has_arg = 0, .flag = &ipv6_flag, .val = 1},
2333+
{ .name = "ipv6-addr", .has_arg = 0, .flag = &ipv6_addr_flag, .val = 1},
23292334
#ifdef HAVE_IPV6
23302335
{ .name = "raw_ipv6", .has_arg = 0, .flag = &raw_ipv6_flag, .val = 1},
23312336
#endif
@@ -3047,6 +3052,10 @@ int parser(struct perftest_parameters *user_param,char *argv[], int argc)
30473052
user_param->ipv6 = 1;
30483053
}
30493054

3055+
if (ipv6_addr_flag) {
3056+
user_param->ai_family = AF_INET6;
3057+
}
3058+
30503059
if (raw_ipv6_flag) {
30513060
if (user_param->is_new_raw_eth_param) {
30523061
if (user_param->is_server_ip) {

src/perftest_parameters.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -602,6 +602,7 @@ struct perftest_parameters {
602602
int dont_xchg_versions;
603603
int ipv6;
604604
int raw_ipv6;
605+
int ai_family;
605606
int report_per_port;
606607
int use_odp;
607608
int use_hugepages;

src/perftest_resources.c

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -831,13 +831,30 @@ int check_add_port(char **service,int port,
831831
free(*service);
832832

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

838839
return SUCCESS;
839840
}
840841

842+
/******************************************************************************
843+
*
844+
******************************************************************************/
845+
int sockaddr_set_port(struct sockaddr *sin,int port)
846+
{
847+
switch (sin->sa_family) {
848+
case AF_INET: ((struct sockaddr_in*) sin)->sin_port = htons(port);
849+
break;
850+
case AF_INET6: ((struct sockaddr_in6*) sin)->sin6_port = htons(port);
851+
break;
852+
default:
853+
fprintf(stderr, "ai_family: %x is not yet supported\n", sin->sa_family);
854+
return FAILURE;
855+
}
856+
return SUCCESS;
857+
}
841858
/******************************************************************************
842859
*
843860
******************************************************************************/

src/perftest_resources.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,19 @@ int check_add_port(char **service,int port,
260260
struct addrinfo *hints,
261261
struct addrinfo **res);
262262

263+
/* sockaddr_set_port
264+
*
265+
* Description : Initialize port for given sockaddr structure
266+
*
267+
* Parameters :
268+
* service - an empty char** to contain the service name.
269+
* port - The selected port on which the server will listen.
270+
* sin - sockaddr params for the connection.
271+
*
272+
* Return Value : SUCCESS, FAILURE.
273+
*/
274+
int sockaddr_set_port(struct sockaddr *sin,int port);
275+
263276
/* ctx_find_dev
264277
*
265278
* Description : Returns the device corresponding to ib_devname

0 commit comments

Comments
 (0)