examples/ip_pipeline: add link identification
authorFan Zhang <roy.fan.zhang@intel.com>
Tue, 1 Mar 2016 10:35:52 +0000 (10:35 +0000)
committerThomas Monjalon <thomas.monjalon@6wind.com>
Mon, 7 Mar 2016 11:43:23 +0000 (12:43 +0100)
This patch adds link identification feature to packet framework. To
identify a link, user can use both existing port-mask option, or specify
PCI device in every LINK section in the configuration file.

Signed-off-by: Fan Zhang <roy.fan.zhang@intel.com>
Acked-by: Cristian Dumitrescu <cristian.dumitrescu@intel.com>
examples/ip_pipeline/app.h
examples/ip_pipeline/config_check.c
examples/ip_pipeline/config_parse.c
examples/ip_pipeline/init.c
examples/ip_pipeline/pipeline/pipeline_common_fe.c

index 2c91256..f55aef8 100644 (file)
@@ -49,7 +49,7 @@
 #include "pipeline.h"
 
 #define APP_PARAM_NAME_SIZE                      PIPELINE_NAME_SIZE
-
+#define APP_LINK_PCI_BDF_SIZE                    16
 struct app_mempool_params {
        char *name;
        uint32_t parsed;
@@ -64,7 +64,7 @@ struct app_link_params {
        uint32_t parsed;
        uint32_t pmd_id; /* Generated based on port mask */
        uint32_t arp_q; /* 0 = Disabled (packets go to default queue 0) */
-       uint32_t tcp_syn_local_q; /* 0 = Disabled (pkts go to default queue) */
+       uint32_t tcp_syn_q; /* 0 = Disabled (pkts go to default queue) */
        uint32_t ip_local_q; /* 0 = Disabled (pkts go to default queue 0) */
        uint32_t tcp_local_q; /* 0 = Disabled (pkts go to default queue 0) */
        uint32_t udp_local_q; /* 0 = Disabled (pkts go to default queue 0) */
@@ -73,6 +73,7 @@ struct app_link_params {
        uint32_t ip; /* 0 = Invalid */
        uint32_t depth; /* Valid only when IP is valid */
        uint64_t mac_addr; /* Read from HW */
+       char pci_bdf[APP_LINK_PCI_BDF_SIZE];
 
        struct rte_eth_conf conf;
        uint8_t promisc;
@@ -269,6 +270,10 @@ struct app_thread_data {
        double headroom_ratio;
 };
 
+#ifndef APP_MAX_LINKS
+#define APP_MAX_LINKS                            16
+#endif
+
 struct app_eal_params {
        /* Map lcore set to physical cpu set */
        char *coremap;
@@ -290,13 +295,13 @@ struct app_eal_params {
        uint32_t ranks;
 
        /* Add a PCI device in black list. */
-       char *pci_blacklist;
+       char *pci_blacklist[APP_MAX_LINKS];
 
        /* Add a PCI device in white list. */
-       char *pci_whitelist;
+       char *pci_whitelist[APP_MAX_LINKS];
 
        /* Add a virtual device. */
-       char *vdev;
+       char *vdev[APP_MAX_LINKS];
 
         /* Use VMware TSC map instead of native RDTSC */
        uint32_t vmware_tsc_map_present;
@@ -371,10 +376,6 @@ struct app_eal_params {
 #define APP_MAX_MEMPOOLS                         8
 #endif
 
-#ifndef APP_MAX_LINKS
-#define APP_MAX_LINKS                            16
-#endif
-
 #ifndef APP_LINK_MAX_HWQ_IN
 #define APP_LINK_MAX_HWQ_IN                      64
 #endif
index 1ff5763..fd9ff49 100644 (file)
@@ -59,12 +59,16 @@ check_mempools(struct app_params *app)
 static void
 check_links(struct app_params *app)
 {
-       uint32_t n_links_port_mask = __builtin_popcountll(app->port_mask);
        uint32_t i;
 
        /* Check that number of links matches the port mask */
-       APP_CHECK((app->n_links == n_links_port_mask),
-               "Not enough links provided in the PORT_MASK\n");
+       if (app->port_mask) {
+               uint32_t n_links_port_mask =
+                       __builtin_popcountll(app->port_mask);
+
+               APP_CHECK((app->n_links == n_links_port_mask),
+                       "Not enough links provided in the PORT_MASK\n");
+       }
 
        for (i = 0; i < app->n_links; i++) {
                struct app_link_params *link = &app->link_params[i];
@@ -76,8 +80,8 @@ check_links(struct app_params *app)
                rxq_max = 0;
                if (link->arp_q > rxq_max)
                        rxq_max = link->arp_q;
-               if (link->tcp_syn_local_q > rxq_max)
-                       rxq_max = link->tcp_syn_local_q;
+               if (link->tcp_syn_q > rxq_max)
+                       rxq_max = link->tcp_syn_q;
                if (link->ip_local_q > rxq_max)
                        rxq_max = link->ip_local_q;
                if (link->tcp_local_q > rxq_max)
@@ -89,7 +93,7 @@ check_links(struct app_params *app)
 
                for (i = 1; i <= rxq_max; i++)
                        APP_CHECK(((link->arp_q == i) ||
-                               (link->tcp_syn_local_q == i) ||
+                               (link->tcp_syn_q == i) ||
                                (link->ip_local_q == i) ||
                                (link->tcp_local_q == i) ||
                                (link->udp_local_q == i) ||
index 5f72af9..4695ac1 100644 (file)
@@ -56,6 +56,7 @@
 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,
@@ -74,7 +75,7 @@ static const struct app_link_params link_params_default = {
        .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,
@@ -83,6 +84,7 @@ static const struct app_link_params link_params_default = {
        .ip = 0,
        .depth = 0,
        .mac_addr = 0,
+       .pci_bdf = {0},
 
        .conf = {
                .link_speed = 0,
@@ -205,12 +207,13 @@ struct app_pipeline_params default_pipeline_params = {
 };
 
 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"
@@ -283,6 +286,11 @@ parser_read_arg_bool(const char *p)
 #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")
 
@@ -657,29 +665,62 @@ parse_eal(struct app_params *app,
                /* 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;
                }
 
@@ -1395,6 +1436,7 @@ parse_link(struct app_params *app,
        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);
@@ -1433,7 +1475,7 @@ parse_link(struct app_params *app,
 
                if (strcmp(ent->name, "tcp_syn_q") == 0) {
                        int status = parser_read_uint32(
-                               &param->tcp_syn_local_q, ent->value);
+                               &param->tcp_syn_q, ent->value);
 
                        PARSE_ERROR((status == 0), section_name, ent->name);
                        continue;
@@ -1476,10 +1518,31 @@ parse_link(struct app_params *app,
                        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);
@@ -2121,7 +2184,8 @@ create_implicit_mempools(struct app_params *app)
 }
 
 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;
 
@@ -2142,6 +2206,18 @@ parse_port_mask(struct app_params *app, uint64_t port_mask)
        }
 }
 
+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)
 {
@@ -2153,7 +2229,8 @@ 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);
@@ -2232,6 +2309,9 @@ app_config_parse(struct app_params *app, const char *file_name)
        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);
 
@@ -2245,6 +2325,7 @@ static void
 save_eal_params(struct app_params *app, FILE *f)
 {
        struct app_eal_params *p = &app->eal_params;
+       uint32_t i;
 
        fprintf(f, "[EAL]\n");
 
@@ -2263,14 +2344,29 @@ save_eal_params(struct app_params *app, FILE *f)
        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",
@@ -2371,14 +2467,17 @@ save_links_params(struct app_params *app, FILE *f)
                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);
        }
 }
@@ -2891,10 +2990,6 @@ app_config_args(struct app_params *app, int argc, char **argv)
 
        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 "
index af47835..2d9fae4 100644 (file)
@@ -96,9 +96,10 @@ app_init_core_mask(struct app_params *app)
 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);
@@ -132,24 +133,47 @@ app_init_eal(struct app_params *app)
                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);
        }
 
@@ -267,6 +291,15 @@ app_init_eal(struct app_params *app)
        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");
@@ -317,7 +350,7 @@ app_link_filter_tcp_syn_add(struct app_link_params *link)
 {
        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,
@@ -555,28 +588,45 @@ app_link_set_arp_filter(struct app_params *app, struct app_link_params *cp)
 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++) {
@@ -671,8 +721,8 @@ app_link_up_internal(struct app_params *app, struct app_link_params *cp)
        /* 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;
@@ -682,9 +732,18 @@ void
 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;
index 1e16ad6..bffc9a4 100644 (file)
@@ -898,9 +898,15 @@ print_link_info(struct app_link_params *p)
 
        mac_addr = (struct ether_addr *) &p->mac_addr;
 
-       printf("%s: flags=<%s>\n",
-               p->name,
-               (p->state) ? "UP" : "DOWN");
+       if (strlen(p->pci_bdf))
+               printf("%s(%s): flags=<%s>\n",
+                       p->name,
+                       p->pci_bdf,
+                       (p->state) ? "UP" : "DOWN");
+       else
+               printf("%s: flags=<%s>\n",
+                       p->name,
+                       (p->state) ? "UP" : "DOWN");
 
        if (p->ip)
                printf("\tinet %" PRIu32 ".%" PRIu32