net: zperf: Add support for bind to host option for tcp/udp download
The current zperf tcp/udp download command doesn't provide the option to bind the server to a specific host address. If there is more than one interface, it will not be possible to test each interface with zperf tcp/udp download command without building the Zpehyr. This patch will add support for zperf tcp/udp download command to bind server to host interface address. Signed-off-by: Rahul Singh <rahul.singh@arm.com>
This commit is contained in:
parent
c8a79e1fc1
commit
6ef75a26ea
4 changed files with 84 additions and 20 deletions
|
@ -43,6 +43,7 @@ struct zperf_upload_params {
|
|||
|
||||
struct zperf_download_params {
|
||||
uint16_t port;
|
||||
struct sockaddr addr;
|
||||
};
|
||||
|
||||
struct zperf_results {
|
||||
|
|
|
@ -178,6 +178,39 @@ static int parse_ipv4_addr(const struct shell *sh, char *host, char *port,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int zperf_bind_host(const struct shell *sh,
|
||||
size_t argc, char *argv[],
|
||||
struct zperf_download_params *param)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* Parse options */
|
||||
if (argc >= 2) {
|
||||
param->port = strtoul(argv[1], NULL, 10);
|
||||
} else {
|
||||
param->port = DEF_PORT;
|
||||
}
|
||||
|
||||
if (argc >= 3) {
|
||||
char *addr_str = argv[2];
|
||||
struct sockaddr addr;
|
||||
|
||||
memset(&addr, 0, sizeof(addr));
|
||||
|
||||
ret = net_ipaddr_parse(addr_str, strlen(addr_str), &addr);
|
||||
if (ret < 0) {
|
||||
shell_fprintf(sh, SHELL_WARNING,
|
||||
"Cannot parse address \"%s\"\n",
|
||||
addr_str);
|
||||
return ret;
|
||||
}
|
||||
|
||||
memcpy(¶m->addr, &addr, sizeof(struct sockaddr));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cmd_setip(const struct shell *sh, size_t argc, char *argv[])
|
||||
{
|
||||
int start = 0;
|
||||
|
@ -333,10 +366,12 @@ static int cmd_udp_download(const struct shell *sh, size_t argc,
|
|||
struct zperf_download_params param = { 0 };
|
||||
int ret;
|
||||
|
||||
if (argc >= 2) {
|
||||
param.port = strtoul(argv[1], NULL, 10);
|
||||
} else {
|
||||
param.port = DEF_PORT;
|
||||
ret = zperf_bind_host(sh, argc, argv, ¶m);
|
||||
if (ret < 0) {
|
||||
shell_fprintf(sh, SHELL_WARNING,
|
||||
"Unable to bind host.\n");
|
||||
shell_help(sh);
|
||||
return -ENOEXEC;
|
||||
}
|
||||
|
||||
ret = zperf_udp_download(¶m, udp_session_cb, (void *)sh);
|
||||
|
@ -1120,10 +1155,12 @@ static int cmd_tcp_download(const struct shell *sh, size_t argc,
|
|||
struct zperf_download_params param = { 0 };
|
||||
int ret;
|
||||
|
||||
if (argc >= 2) {
|
||||
param.port = strtoul(argv[1], NULL, 10);
|
||||
} else {
|
||||
param.port = DEF_PORT;
|
||||
ret = zperf_bind_host(sh, argc, argv, ¶m);
|
||||
if (ret < 0) {
|
||||
shell_fprintf(sh, SHELL_WARNING,
|
||||
"Unable to bind host.\n");
|
||||
shell_help(sh);
|
||||
return -ENOEXEC;
|
||||
}
|
||||
|
||||
ret = zperf_tcp_download(¶m, tcp_session_cb, (void *)sh);
|
||||
|
@ -1254,8 +1291,9 @@ SHELL_STATIC_SUBCMD_SET_CREATE(zperf_cmd_tcp,
|
|||
,
|
||||
cmd_tcp_upload2),
|
||||
SHELL_CMD(download, &zperf_cmd_tcp_download,
|
||||
"[<port>]\n"
|
||||
"Example: tcp download 5001\n",
|
||||
"[<port>]: Server port to listen on/connect to\n"
|
||||
"[<host>]: Bind to <host>, an interface address\n"
|
||||
"Example: tcp download 5001 192.168.0.1\n",
|
||||
cmd_tcp_download),
|
||||
SHELL_SUBCMD_SET_END
|
||||
);
|
||||
|
@ -1312,8 +1350,9 @@ SHELL_STATIC_SUBCMD_SET_CREATE(zperf_cmd_udp,
|
|||
,
|
||||
cmd_udp_upload2),
|
||||
SHELL_CMD(download, &zperf_cmd_udp_download,
|
||||
"[<port>]\n"
|
||||
"Example: udp download 5001\n",
|
||||
"[<port>]: Server port to listen on/connect to\n"
|
||||
"[<host>]: Bind to <host>, an interface address\n"
|
||||
"Example: udp download 5001 192.168.0.1\n",
|
||||
cmd_udp_download),
|
||||
SHELL_SUBCMD_SET_END
|
||||
);
|
||||
|
|
|
@ -46,6 +46,7 @@ static void *tcp_user_data;
|
|||
static bool tcp_server_running;
|
||||
static bool tcp_server_stop;
|
||||
static uint16_t tcp_server_port;
|
||||
static struct sockaddr tcp_server_addr;
|
||||
static K_SEM_DEFINE(tcp_server_run, 0, 1);
|
||||
|
||||
static void tcp_received(const struct sockaddr *addr, size_t datalen)
|
||||
|
@ -150,6 +151,7 @@ static void tcp_server_session(void)
|
|||
|
||||
if (IS_ENABLED(CONFIG_NET_IPV4)) {
|
||||
struct sockaddr_in *in4_addr = zperf_get_sin();
|
||||
const struct in_addr *addr = NULL;
|
||||
|
||||
fds[SOCK_ID_IPV4_LISTEN].fd = zsock_socket(AF_INET, SOCK_STREAM,
|
||||
IPPROTO_TCP);
|
||||
|
@ -158,7 +160,12 @@ static void tcp_server_session(void)
|
|||
goto error;
|
||||
}
|
||||
|
||||
if (MY_IP4ADDR && strlen(MY_IP4ADDR)) {
|
||||
addr = &net_sin(&tcp_server_addr)->sin_addr;
|
||||
|
||||
if (!net_ipv4_is_addr_unspecified(addr)) {
|
||||
memcpy(&in4_addr->sin_addr, addr,
|
||||
sizeof(struct in_addr));
|
||||
} else if (MY_IP4ADDR && strlen(MY_IP4ADDR)) {
|
||||
/* Use Setting IP */
|
||||
ret = zperf_get_ipv4_addr(MY_IP4ADDR,
|
||||
&in4_addr->sin_addr);
|
||||
|
@ -167,9 +174,8 @@ static void tcp_server_session(void)
|
|||
goto use_existing_ipv4;
|
||||
}
|
||||
} else {
|
||||
/* Use existing IP */
|
||||
const struct in_addr *addr;
|
||||
use_existing_ipv4:
|
||||
/* Use existing IP */
|
||||
addr = zperf_get_default_if_in4_addr();
|
||||
if (!addr) {
|
||||
NET_ERR("Unable to get IPv4 by default");
|
||||
|
@ -197,6 +203,7 @@ use_existing_ipv4:
|
|||
|
||||
if (IS_ENABLED(CONFIG_NET_IPV6)) {
|
||||
struct sockaddr_in6 *in6_addr = zperf_get_sin6();
|
||||
const struct in6_addr *addr = NULL;
|
||||
|
||||
fds[SOCK_ID_IPV6_LISTEN].fd = zsock_socket(AF_INET6, SOCK_STREAM,
|
||||
IPPROTO_TCP);
|
||||
|
@ -205,7 +212,12 @@ use_existing_ipv4:
|
|||
goto error;
|
||||
}
|
||||
|
||||
if (MY_IP6ADDR && strlen(MY_IP6ADDR)) {
|
||||
addr = &net_sin6(&tcp_server_addr)->sin6_addr;
|
||||
|
||||
if (!net_ipv6_is_addr_unspecified(addr)) {
|
||||
memcpy(&in6_addr->sin6_addr, addr,
|
||||
sizeof(struct in6_addr));
|
||||
} else if (MY_IP6ADDR && strlen(MY_IP6ADDR)) {
|
||||
/* Use Setting IP */
|
||||
ret = zperf_get_ipv6_addr(MY_IP6ADDR,
|
||||
MY_PREFIX_LEN_STR,
|
||||
|
@ -215,9 +227,8 @@ use_existing_ipv4:
|
|||
goto use_existing_ipv6;
|
||||
}
|
||||
} else {
|
||||
/* Use existing IP */
|
||||
const struct in6_addr *addr;
|
||||
use_existing_ipv6:
|
||||
/* Use existing IP */
|
||||
addr = zperf_get_default_if_in6_addr();
|
||||
if (!addr) {
|
||||
NET_ERR("Unable to get IPv6 by default");
|
||||
|
@ -387,6 +398,7 @@ int zperf_tcp_download(const struct zperf_download_params *param,
|
|||
tcp_server_port = param->port;
|
||||
tcp_server_running = true;
|
||||
tcp_server_stop = false;
|
||||
memcpy(&tcp_server_addr, ¶m->addr, sizeof(struct sockaddr));
|
||||
|
||||
k_sem_give(&tcp_server_run);
|
||||
|
||||
|
|
|
@ -48,6 +48,7 @@ static void *udp_user_data;
|
|||
static bool udp_server_running;
|
||||
static bool udp_server_stop;
|
||||
static uint16_t udp_server_port;
|
||||
static struct sockaddr udp_server_addr;
|
||||
static K_SEM_DEFINE(udp_server_run, 0, 1);
|
||||
|
||||
static inline void build_reply(struct zperf_udp_datagram *hdr,
|
||||
|
@ -251,7 +252,12 @@ static void udp_server_session(void)
|
|||
goto error;
|
||||
}
|
||||
|
||||
if (MY_IP4ADDR && strlen(MY_IP4ADDR)) {
|
||||
in4_addr = &net_sin(&udp_server_addr)->sin_addr;
|
||||
|
||||
if (!net_ipv4_is_addr_unspecified(in4_addr)) {
|
||||
memcpy(&in4_addr_my->sin_addr, in4_addr,
|
||||
sizeof(struct in_addr));
|
||||
} else if (MY_IP4ADDR && strlen(MY_IP4ADDR)) {
|
||||
/* Use setting IP */
|
||||
ret = zperf_get_ipv4_addr(MY_IP4ADDR,
|
||||
&in4_addr_my->sin_addr);
|
||||
|
@ -301,7 +307,12 @@ static void udp_server_session(void)
|
|||
goto error;
|
||||
}
|
||||
|
||||
if (MY_IP6ADDR && strlen(MY_IP6ADDR)) {
|
||||
in6_addr = &net_sin6(&udp_server_addr)->sin6_addr;
|
||||
|
||||
if (!net_ipv6_is_addr_unspecified(in6_addr)) {
|
||||
memcpy(&in6_addr_my->sin6_addr, in6_addr,
|
||||
sizeof(struct in6_addr));
|
||||
} else if (MY_IP6ADDR && strlen(MY_IP6ADDR)) {
|
||||
/* Use setting IP */
|
||||
ret = zperf_get_ipv6_addr(MY_IP6ADDR,
|
||||
MY_PREFIX_LEN_STR,
|
||||
|
@ -441,6 +452,7 @@ int zperf_udp_download(const struct zperf_download_params *param,
|
|||
udp_server_port = param->port;
|
||||
udp_server_running = true;
|
||||
udp_server_stop = false;
|
||||
memcpy(&udp_server_addr, ¶m->addr, sizeof(struct sockaddr));
|
||||
|
||||
k_sem_give(&udp_server_run);
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue