examples/multi_process: check server port validity
The mp_server incorrectly allows a port mask that included hidden ports and which later caused either lost packets or failed initialization. This fixes explicitly checking that each bit in portmask is a valid port before using it. Fixes: 5b7ba31148a8 ("ethdev: add port ownership") Cc: stable@dpdk.org Signed-off-by: Stephen Hemminger <sthemmin@microsoft.com> Acked-by: Matan Azrad <matan@mellanox.com>
This commit is contained in:
parent
1b32cc619b
commit
1f41d98c20
@ -10,6 +10,7 @@
|
||||
#include <errno.h>
|
||||
|
||||
#include <rte_memory.h>
|
||||
#include <rte_ethdev.h>
|
||||
#include <rte_string_fns.h>
|
||||
|
||||
#include "common.h"
|
||||
@ -41,31 +42,34 @@ usage(void)
|
||||
* array variable
|
||||
*/
|
||||
static int
|
||||
parse_portmask(uint8_t max_ports, const char *portmask)
|
||||
parse_portmask(const char *portmask)
|
||||
{
|
||||
char *end = NULL;
|
||||
unsigned long pm;
|
||||
uint16_t count = 0;
|
||||
unsigned long long pm;
|
||||
uint16_t id;
|
||||
|
||||
if (portmask == NULL || *portmask == '\0')
|
||||
return -1;
|
||||
|
||||
/* convert parameter to a number and verify */
|
||||
pm = strtoul(portmask, &end, 16);
|
||||
if (end == NULL || *end != '\0' || pm == 0)
|
||||
errno = 0;
|
||||
pm = strtoull(portmask, &end, 16);
|
||||
if (errno != 0 || end == NULL || *end != '\0')
|
||||
return -1;
|
||||
|
||||
/* loop through bits of the mask and mark ports */
|
||||
while (pm != 0){
|
||||
if (pm & 0x01){ /* bit is set in mask, use port */
|
||||
if (count >= max_ports)
|
||||
printf("WARNING: requested port %u not present"
|
||||
" - ignoring\n", (unsigned)count);
|
||||
else
|
||||
ports->id[ports->num_ports++] = count;
|
||||
}
|
||||
pm = (pm >> 1);
|
||||
count++;
|
||||
RTE_ETH_FOREACH_DEV(id) {
|
||||
unsigned long msk = 1u << id;
|
||||
|
||||
if ((pm & msk) == 0)
|
||||
continue;
|
||||
|
||||
pm &= ~msk;
|
||||
ports->id[ports->num_ports++] = id;
|
||||
}
|
||||
|
||||
if (pm != 0) {
|
||||
printf("WARNING: leftover ports in mask %#llx - ignoring\n",
|
||||
pm);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -99,7 +103,7 @@ parse_num_clients(const char *clients)
|
||||
* on error.
|
||||
*/
|
||||
int
|
||||
parse_app_args(uint16_t max_ports, int argc, char *argv[])
|
||||
parse_app_args(int argc, char *argv[])
|
||||
{
|
||||
int option_index, opt;
|
||||
char **argvopt = argv;
|
||||
@ -112,7 +116,7 @@ parse_app_args(uint16_t max_ports, int argc, char *argv[])
|
||||
&option_index)) != EOF){
|
||||
switch (opt){
|
||||
case 'p':
|
||||
if (parse_portmask(max_ports, optarg) != 0){
|
||||
if (parse_portmask(optarg) != 0) {
|
||||
usage();
|
||||
return -1;
|
||||
}
|
||||
|
@ -5,6 +5,6 @@
|
||||
#ifndef _ARGS_H_
|
||||
#define _ARGS_H_
|
||||
|
||||
int parse_app_args(uint16_t max_ports, int argc, char *argv[]);
|
||||
int parse_app_args(int argc, char *argv[]);
|
||||
|
||||
#endif /* ifndef _ARGS_H_ */
|
||||
|
@ -248,7 +248,7 @@ init(int argc, char *argv[])
|
||||
{
|
||||
int retval;
|
||||
const struct rte_memzone *mz;
|
||||
uint16_t i, total_ports;
|
||||
uint16_t i;
|
||||
|
||||
/* init EAL, parsing EAL args */
|
||||
retval = rte_eal_init(argc, argv);
|
||||
@ -257,9 +257,6 @@ init(int argc, char *argv[])
|
||||
argc -= retval;
|
||||
argv += retval;
|
||||
|
||||
/* get total number of ports */
|
||||
total_ports = rte_eth_dev_count_total();
|
||||
|
||||
/* set up array for port data */
|
||||
mz = rte_memzone_reserve(MZ_PORT_INFO, sizeof(*ports),
|
||||
rte_socket_id(), NO_FLAGS);
|
||||
@ -269,7 +266,7 @@ init(int argc, char *argv[])
|
||||
ports = mz->addr;
|
||||
|
||||
/* parse additional, application arguments */
|
||||
retval = parse_app_args(total_ports, argc, argv);
|
||||
retval = parse_app_args(argc, argv);
|
||||
if (retval != 0)
|
||||
return -1;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user