static struct app_params app_params_default = {
.config_file = "./config/ip_pipeline.cfg",
.log_level = APP_LOG_LEVEL_HIGH,
+ .port_mask = 0,
.eal_params = {
.channels = 4,
.parsed = 0,
.pmd_id = 0,
.arp_q = 0,
- .tcp_syn_local_q = 0,
+ .tcp_syn_q = 0,
.ip_local_q = 0,
.tcp_local_q = 0,
.udp_local_q = 0,
.ip = 0,
.depth = 0,
.mac_addr = 0,
+ .pci_bdf = {0},
.conf = {
.link_speed = 0,
};
static const char app_usage[] =
- "Usage: %s [-f CONFIG_FILE] [-s SCRIPT_FILE] -p PORT_MASK "
+ "Usage: %s [-f CONFIG_FILE] [-s SCRIPT_FILE] [-p PORT_MASK] "
"[-l LOG_LEVEL] [--preproc PREPROCESSOR] [--preproc-args ARGS]\n"
"\n"
"Arguments:\n"
"\t-f CONFIG_FILE: Default config file is %s\n"
- "\t-p PORT_MASK: Mask of NIC port IDs in hexadecimal format\n"
+ "\t-p PORT_MASK: Mask of NIC port IDs in hex format (generated from "
+ "config file when not provided)\n"
"\t-s SCRIPT_FILE: No CLI script file is run when not specified\n"
"\t-l LOG_LEVEL: 0 = NONE, 1 = HIGH PRIO (default), 2 = LOW PRIO\n"
"\t--preproc PREPROCESSOR: Configuration file pre-processor\n"
#define PARSE_ERROR(exp, section, entry) \
APP_CHECK(exp, "Parse error in section \"%s\": entry \"%s\"\n", section, entry)
+#define PARSE_ERROR_MESSAGE(exp, section, entry, message) \
+APP_CHECK(exp, "Parse error in section \"%s\", entry \"%s\": %s\n", \
+ section, entry, message)
+
+
#define PARSE_ERROR_MALLOC(exp) \
APP_CHECK(exp, "Parse error: no free memory\n")
/* pci_blacklist */
if ((strcmp(entry->name, "pci_blacklist") == 0) ||
(strcmp(entry->name, "b") == 0)) {
- PARSE_ERROR_DUPLICATE((p->pci_blacklist == NULL),
- section_name,
- entry->name);
- p->pci_blacklist = strdup(entry->value);
+ uint32_t i;
+
+ for (i = 0; i < APP_MAX_LINKS; i++) {
+ if (p->pci_blacklist[i])
+ continue;
+
+ p->pci_blacklist[i] =
+ strdup(entry->value);
+ PARSE_ERROR_MALLOC(p->pci_blacklist[i]);
+ }
+
+ PARSE_ERROR_MESSAGE((i < APP_MAX_LINKS),
+ section_name, entry->name,
+ "too many elements");
continue;
}
/* pci_whitelist */
if ((strcmp(entry->name, "pci_whitelist") == 0) ||
(strcmp(entry->name, "w") == 0)) {
- PARSE_ERROR_DUPLICATE((p->pci_whitelist == NULL),
- section_name,
- entry->name);
- p->pci_whitelist = strdup(entry->value);
+ uint32_t i;
+
+ PARSE_ERROR_MESSAGE((app->port_mask != 0),
+ section_name, entry->name, "entry to be "
+ "generated by the application (port_mask "
+ "not provided)");
+
+ for (i = 0; i < APP_MAX_LINKS; i++) {
+ if (p->pci_whitelist[i])
+ continue;
+
+ p->pci_whitelist[i] = strdup(entry->value);
+ PARSE_ERROR_MALLOC(p->pci_whitelist[i]);
+ }
+
+ PARSE_ERROR_MESSAGE((i < APP_MAX_LINKS),
+ section_name, entry->name,
+ "too many elements");
continue;
}
/* vdev */
if (strcmp(entry->name, "vdev") == 0) {
- PARSE_ERROR_DUPLICATE((p->vdev == NULL),
- section_name,
- entry->name);
- p->vdev = strdup(entry->value);
+ uint32_t i;
+
+ for (i = 0; i < APP_MAX_LINKS; i++) {
+ if (p->vdev[i])
+ continue;
+
+ p->vdev[i] = strdup(entry->value);
+ PARSE_ERROR_MALLOC(p->vdev[i]);
+ }
+
+ PARSE_ERROR_MESSAGE((i < APP_MAX_LINKS),
+ section_name, entry->name,
+ "too many elements");
continue;
}
struct app_link_params *param;
struct rte_cfgfile_entry *entries;
int n_entries, i;
+ int pci_bdf_present = 0;
ssize_t param_idx;
n_entries = rte_cfgfile_section_num_entries(cfg, section_name);
if (strcmp(ent->name, "tcp_syn_q") == 0) {
int status = parser_read_uint32(
- ¶m->tcp_syn_local_q, ent->value);
+ ¶m->tcp_syn_q, ent->value);
PARSE_ERROR((status == 0), section_name, ent->name);
continue;
continue;
}
+ if (strcmp(ent->name, "pci_bdf") == 0) {
+ PARSE_ERROR_DUPLICATE((pci_bdf_present == 0),
+ section_name, ent->name);
+
+ snprintf(param->pci_bdf, APP_LINK_PCI_BDF_SIZE,
+ "%s", ent->value);
+ pci_bdf_present = 1;
+ continue;
+ }
+
/* unrecognized */
PARSE_ERROR_INVALID(0, section_name, ent->name);
}
+ /* Check for mandatory fields */
+ if (app->port_mask)
+ PARSE_ERROR_MESSAGE((pci_bdf_present == 0),
+ section_name, "pci_bdf",
+ "entry not allowed (port_mask is provided)");
+ else
+ PARSE_ERROR_MESSAGE((pci_bdf_present),
+ section_name, "pci_bdf",
+ "this entry is mandatory (port_mask is not "
+ "provided)");
+
param->parsed = 1;
free(entries);
}
static void
-parse_port_mask(struct app_params *app, uint64_t port_mask)
+create_implicit_links_from_port_mask(struct app_params *app,
+ uint64_t port_mask)
{
uint32_t pmd_id, link_id;
}
}
+static void
+assign_link_pmd_id_from_pci_bdf(struct app_params *app)
+{
+ uint32_t i;
+
+ for (i = 0; i < app->n_links; i++) {
+ struct app_link_params *link = &app->link_params[i];
+
+ link->pmd_id = i;
+ }
+}
+
int
app_config_parse(struct app_params *app, const char *file_name)
{
create_implicit_mempools(app);
/* Port mask */
- parse_port_mask(app, app->port_mask);
+ if (app->port_mask)
+ create_implicit_links_from_port_mask(app, app->port_mask);
/* Load application configuration file */
cfg = rte_cfgfile_load(file_name, 0);
APP_PARAM_COUNT(app->msgq_params, app->n_msgq);
APP_PARAM_COUNT(app->pipeline_params, app->n_pipelines);
+ if (app->port_mask == 0)
+ assign_link_pmd_id_from_pci_bdf(app);
+
/* Save configuration to output file */
app_config_save(app, app->output_file);
save_eal_params(struct app_params *app, FILE *f)
{
struct app_eal_params *p = &app->eal_params;
+ uint32_t i;
fprintf(f, "[EAL]\n");
if (p->ranks_present)
fprintf(f, "%s = %" PRIu32 "\n", "r", p->ranks);
- if (p->pci_blacklist)
- fprintf(f, "%s = %s\n", "pci_blacklist", p->pci_blacklist);
+ for (i = 0; i < APP_MAX_LINKS; i++) {
+ if (p->pci_blacklist[i] == NULL)
+ break;
+
+ fprintf(f, "%s = %s\n", "pci_blacklist",
+ p->pci_blacklist[i]);
+ }
- if (p->pci_whitelist)
- fprintf(f, "%s = %s\n", "pci_whitelist", p->pci_whitelist);
+ for (i = 0; i < APP_MAX_LINKS; i++) {
+ if (p->pci_whitelist[i] == NULL)
+ break;
- if (p->vdev)
- fprintf(f, "%s = %s\n", "vdev", p->vdev);
+ fprintf(f, "%s = %s\n", "pci_whitelist",
+ p->pci_whitelist[i]);
+ }
+
+ for (i = 0; i < APP_MAX_LINKS; i++) {
+ if (p->vdev[i] == NULL)
+ break;
+
+ fprintf(f, "%s = %s\n", "vdev",
+ p->vdev[i]);
+ }
if (p->vmware_tsc_map_present)
fprintf(f, "%s = %s\n", "vmware_tsc_map",
fprintf(f, "; %s = %" PRIu32 "\n", "pmd_id", p->pmd_id);
fprintf(f, "%s = %s\n", "promisc", p->promisc ? "yes" : "no");
fprintf(f, "%s = %" PRIu32 "\n", "arp_q", p->arp_q);
- fprintf(f, "%s = %" PRIu32 "\n", "tcp_syn_local_q",
- p->tcp_syn_local_q);
+ fprintf(f, "%s = %" PRIu32 "\n", "tcp_syn_q",
+ p->tcp_syn_q);
fprintf(f, "%s = %" PRIu32 "\n", "ip_local_q", p->ip_local_q);
fprintf(f, "%s = %" PRIu32 "\n", "tcp_local_q", p->tcp_local_q);
fprintf(f, "%s = %" PRIu32 "\n", "udp_local_q", p->udp_local_q);
fprintf(f, "%s = %" PRIu32 "\n", "sctp_local_q",
p->sctp_local_q);
+ if (strlen(p->pci_bdf))
+ fprintf(f, "%s = %s\n", "pci_bdf", p->pci_bdf);
+
fputc('\n', f);
}
}
optind = 0; /* reset getopt lib */
- /* Check that mandatory args have been provided */
- if (!p_present)
- rte_panic("Error: PORT_MASK is not provided\n");
-
/* Check dependencies between args */
if (preproc_params_present && (preproc_present == 0))
rte_panic("Error: Preprocessor args specified while "
static void
app_init_eal(struct app_params *app)
{
- char buffer[32];
+ char buffer[256];
struct app_eal_params *p = &app->eal_params;
uint32_t n_args = 0;
+ uint32_t i;
int status;
app->eal_argv[n_args++] = strdup(app->app_name);
app->eal_argv[n_args++] = strdup(buffer);
}
- if (p->pci_blacklist) {
+ for (i = 0; i < APP_MAX_LINKS; i++) {
+ if (p->pci_blacklist[i] == NULL)
+ break;
+
snprintf(buffer,
sizeof(buffer),
"--pci-blacklist=%s",
- p->pci_blacklist);
+ p->pci_blacklist[i]);
app->eal_argv[n_args++] = strdup(buffer);
}
- if (p->pci_whitelist) {
+ if (app->port_mask != 0)
+ for (i = 0; i < APP_MAX_LINKS; i++) {
+ if (p->pci_whitelist[i] == NULL)
+ break;
+
+ snprintf(buffer,
+ sizeof(buffer),
+ "--pci-whitelist=%s",
+ p->pci_whitelist[i]);
+ app->eal_argv[n_args++] = strdup(buffer);
+ }
+ else
+ for (i = 0; i < app->n_links; i++) {
+ char *pci_bdf = app->link_params[i].pci_bdf;
+
+ snprintf(buffer,
+ sizeof(buffer),
+ "--pci-whitelist=%s",
+ pci_bdf);
+ app->eal_argv[n_args++] = strdup(buffer);
+ }
+
+ for (i = 0; i < APP_MAX_LINKS; i++) {
+ if (p->vdev[i] == NULL)
+ break;
+
snprintf(buffer,
sizeof(buffer),
- "--pci-whitelist=%s",
- p->pci_whitelist);
- app->eal_argv[n_args++] = strdup(buffer);
- }
-
- if (p->vdev) {
- snprintf(buffer, sizeof(buffer), "--vdev=%s", p->vdev);
+ "--vdev=%s",
+ p->vdev[i]);
app->eal_argv[n_args++] = strdup(buffer);
}
app->eal_argc = n_args;
APP_LOG(app, HIGH, "Initializing EAL ...");
+ if (app->log_level >= APP_LOG_LEVEL_LOW) {
+ int i;
+
+ fprintf(stdout, "[APP] EAL arguments: \"");
+ for (i = 1; i < app->eal_argc; i++)
+ fprintf(stdout, "%s ", app->eal_argv[i]);
+ fprintf(stdout, "\"\n");
+ }
+
status = rte_eal_init(app->eal_argc, app->eal_argv);
if (status < 0)
rte_panic("EAL init error\n");
{
struct rte_eth_syn_filter filter = {
.hig_pri = 1,
- .queue = link->tcp_syn_local_q,
+ .queue = link->tcp_syn_q,
};
return rte_eth_dev_filter_ctrl(link->pmd_id,
static void
app_link_set_tcp_syn_filter(struct app_params *app, struct app_link_params *cp)
{
- if (cp->tcp_syn_local_q != 0) {
+ if (cp->tcp_syn_q != 0) {
int status = app_link_filter_tcp_syn_add(cp);
APP_LOG(app, LOW, "%s (%" PRIu32 "): "
"Adding TCP SYN filter (queue = %" PRIu32 ")",
- cp->name, cp->pmd_id, cp->tcp_syn_local_q);
+ cp->name, cp->pmd_id, cp->tcp_syn_q);
if (status)
rte_panic("%s (%" PRIu32 "): "
"Error adding TCP SYN filter "
"(queue = %" PRIu32 ") (%" PRId32 ")\n",
- cp->name, cp->pmd_id, cp->tcp_syn_local_q,
+ cp->name, cp->pmd_id, cp->tcp_syn_q,
status);
}
}
+static int
+app_link_is_virtual(struct app_link_params *p)
+{
+ uint32_t pmd_id = p->pmd_id;
+ struct rte_eth_dev *dev = &rte_eth_devices[pmd_id];
+
+ if (dev->dev_type == RTE_ETH_DEV_VIRTUAL)
+ return 1;
+
+ return 0;
+}
+
void
app_link_up_internal(struct app_params *app, struct app_link_params *cp)
{
uint32_t i;
int status;
+ if (app_link_is_virtual(cp)) {
+ cp->state = 1;
+ return;
+ }
+
/* For each link, add filters for IP of current link */
if (cp->ip != 0) {
for (i = 0; i < app->n_links; i++) {
/* PMD link up */
status = rte_eth_dev_set_link_up(cp->pmd_id);
if (status < 0)
- rte_panic("%s (%" PRIu32 "): PMD set up error %" PRId32 "\n",
- cp->name, cp->pmd_id, status);
+ rte_panic("%s (%" PRIu32 "): PMD set link up error %"
+ PRId32 "\n", cp->name, cp->pmd_id, status);
/* Mark link as UP */
cp->state = 1;
app_link_down_internal(struct app_params *app, struct app_link_params *cp)
{
uint32_t i;
+ int status;
+
+ if (app_link_is_virtual(cp)) {
+ cp->state = 0;
+ return;
+ }
/* PMD link down */
- rte_eth_dev_set_link_down(cp->pmd_id);
+ status = rte_eth_dev_set_link_down(cp->pmd_id);
+ if (status < 0)
+ rte_panic("%s (%" PRIu32 "): PMD set link down error %"
+ PRId32 "\n", cp->name, cp->pmd_id, status);
/* Mark link as DOWN */
cp->state = 0;