Add support for nop mode with l3 submode 53/46953/3
authorXavier Simonart <xavier.simonart@intel.com>
Thu, 9 Nov 2017 14:57:11 +0000 (15:57 +0100)
committerXavier Simonart <xavier.simonart@intel.com>
Wed, 15 Nov 2017 18:05:17 +0000 (19:05 +0100)
The l3 submode was not supported in nop mode, as the nop mode uses some
specific nop thread (and not generic). When L3 is specified, the nop mode
must use the generic thread. In addition the l3 submode is implemented
differently than other submodes. It is not supported through task_init
structures (i.e. each task does not have to explicitely tell that it
supports l3 submode). But this prevented to run both a nop with no submode
and a nop with a l3 submode. Note that nop with l3 is usually not very useful
 - it handles arp (requests and response) but as nop, it does not swap IP
addresses. So with a real switch, the packets transmitted will be received
back... and l3 mode is usually mainly usefull when using a switch.
 However, there is at least one nop mode where l3 submode makes sense:
when the nop does not transmit. In such cases, for instace used in
conjunction with a gen l3, the nop receives all packets and forward
the arp requests and responses to the master for handling.

Change-Id: I992121db285ba25a11cbb494092a6afc6fe55a58
Signed-off-by: Xavier Simonart <xavier.simonart@intel.com>
VNFs/DPPD-PROX/cmd_parser.c
VNFs/DPPD-PROX/commands.c
VNFs/DPPD-PROX/main.c
VNFs/DPPD-PROX/prox_args.c
VNFs/DPPD-PROX/task_base.h
VNFs/DPPD-PROX/task_init.c
VNFs/DPPD-PROX/task_init.h

index 23cd8d4..f61fbe4 100644 (file)
@@ -327,9 +327,9 @@ static int parse_cmd_rate(const char *str, struct input *input)
 
 int task_is_mode_and_submode(uint32_t lcore_id, uint32_t task_id, const char *mode, const char *sub_mode)
 {
-       struct task_init *t = lcore_cfg[lcore_id].targs[task_id].task_init;
+       struct task_args *targs = &lcore_cfg[lcore_id].targs[task_id];
 
-       return !strcmp(t->mode_str, mode) && !strcmp(t->sub_mode_str, sub_mode);
+       return !strcmp(targs->task_init->mode_str, mode) && !strcmp(targs->sub_mode_str, sub_mode);
 }
 
 int task_is_mode(uint32_t lcore_id, uint32_t task_id, const char *mode)
@@ -341,9 +341,9 @@ int task_is_mode(uint32_t lcore_id, uint32_t task_id, const char *mode)
 
 int task_is_sub_mode(uint32_t lcore_id, uint32_t task_id, const char *sub_mode)
 {
-       struct task_init *t = lcore_cfg[lcore_id].targs[task_id].task_init;
+       struct task_args *targs = &lcore_cfg[lcore_id].targs[task_id];
 
-       return !strcmp(t->sub_mode_str, sub_mode);
+       return !strcmp(targs->sub_mode_str, sub_mode);
 }
 
 static void log_pkt_count(uint32_t count, uint32_t lcore_id, uint32_t task_id)
index adfb690..f4cc1b6 100644 (file)
@@ -106,7 +106,7 @@ static inline void start_l3(struct task_args *targ)
 {
        if (!task_is_master(targ)) {
                if ((targ->nb_txrings != 0) || (targ->nb_txports != 0)) {
-                       if (targ->task_init->flag_features & TASK_FEATURE_L3)
+                       if (targ->flags & TASK_ARG_L3)
                                task_start_l3(targ->tbase, targ);
                }
        }
index 1c4dced..2c362d6 100644 (file)
@@ -94,13 +94,15 @@ static void check_mixed_normal_pipeline(void)
                int all_thread_nop = 1;
                int generic = 0;
                int pipeline = 0;
+               int l3 = 0;
                for (uint8_t task_id = 0; task_id < lconf->n_tasks_all; ++task_id) {
                        struct task_args *targ = &lconf->targs[task_id];
-                       all_thread_nop = all_thread_nop &&
+                       l3 = !strcmp("l3", targ->sub_mode_str);
+                       all_thread_nop = all_thread_nop && !l3 &&
                                targ->task_init->thread_x == thread_nop;
 
                        pipeline = pipeline || targ->task_init->thread_x == thread_pipeline;
-                       generic = generic || targ->task_init->thread_x == thread_generic;
+                       generic = generic || targ->task_init->thread_x == thread_generic || l3;
                }
                PROX_PANIC(generic && pipeline, "Can't run both pipeline and normal thread on same core\n");
 
@@ -127,8 +129,8 @@ static void check_zero_rx(void)
 
 static void check_missing_rx(void)
 {
-       struct lcore_cfg *lconf = NULL, *rx_lconf = NULL;
-       struct task_args *targ, *rx_targ = NULL;
+       struct lcore_cfg *lconf = NULL, *rx_lconf = NULL, *tx_lconf = NULL;
+       struct task_args *targ, *rx_targ = NULL, *tx_targ = NULL;
        struct prox_port_cfg *port;
        uint8_t port_id, rx_port_id, ok;
 
@@ -143,8 +145,30 @@ static void check_missing_rx(void)
 
        lconf = NULL;
        while (core_targ_next(&lconf, &targ, 0) == 0) {
-               if (strcmp(targ->task_init->sub_mode_str, "l3") != 0)
+               if (strcmp(targ->sub_mode_str, "l3") != 0)
                        continue;
+
+               // If the L3 sub_mode receives from a port, check that there is at least one core/task
+               // transmitting to this port in L3 sub_mode
+               for (uint8_t i = 0; i < targ->nb_rxports; ++i) {
+                       rx_port_id = targ->rx_port_queue[i].port;
+                       ok = 0;
+                       tx_lconf = NULL;
+                       while (core_targ_next(&tx_lconf, &tx_targ, 0) == 0) {
+                               port = find_reachable_port(tx_targ);
+                               if (port == NULL)
+                                       continue;
+                                       port_id = port - prox_port_cfg;
+                               if ((rx_port_id == port_id) && (tx_targ->flags & TASK_ARG_L3)){
+                                       ok = 1;
+                                       break;
+                               }
+                       }
+                       PROX_PANIC(ok == 0, "RX L3 sub mode for port %d on core %d task %d, but no core/task transmitting on that port\n", rx_port_id, lconf->id, targ->id);
+               }
+
+               // If the L3 sub_mode transmits to a port, check that there is at least one core/task
+               // receiving from that port in L3 sub_mode.
                port = find_reachable_port(targ);
                if (port == NULL)
                        continue;
@@ -155,7 +179,7 @@ static void check_missing_rx(void)
                while (core_targ_next(&rx_lconf, &rx_targ, 0) == 0) {
                        for (uint8_t i = 0; i < rx_targ->nb_rxports; ++i) {
                                rx_port_id = rx_targ->rx_port_queue[i].port;
-                               if ((rx_port_id == port_id) && (rx_targ->task_init->flag_features & TASK_FEATURE_L3)){
+                               if ((rx_port_id == port_id) && (rx_targ->flags & TASK_ARG_L3)){
                                        ok = 1;
                                        break;
                                }
@@ -522,7 +546,7 @@ static void init_rings(void)
        lconf = NULL;
        struct prox_port_cfg *port;
        while (core_targ_next(&lconf, &starg, 1) == 0) {
-               if ((starg->task_init) && (starg->task_init->flag_features & TASK_FEATURE_L3)) {
+               if ((starg->task_init) && (starg->flags & TASK_ARG_L3)) {
                        struct core_task ct;
                        ct.core = prox_cfg.master;
                        ct.task = 0;
index fd8ea52..bbe2738 100644 (file)
@@ -1252,8 +1252,10 @@ static int get_core_cfg(unsigned sindex, char *str, void *data)
                }
                if (strcmp(sub_mode_str, "l3") == 0) {
                        prox_cfg.flags |= DSF_CTRL_PLANE_ENABLED;
-                       targ->task_init->flag_features |= TASK_FEATURE_L3;
-                       strcpy(targ->task_init->sub_mode_str, "l3");
+                       targ->flags |= TASK_ARG_L3;
+                       strcpy(targ->sub_mode_str, "l3");
+               } else {
+                       strcpy(targ->sub_mode_str, targ->task_init->sub_mode_str);
                }
                return 0;
        }
index 62841e9..ad00962 100644 (file)
@@ -54,7 +54,6 @@
 #define TASK_FEATURE_LUT_QINQ_HASH             0x4000
 #define TASK_FEATURE_RX_ALL                    0x8000
 #define TASK_MULTIPLE_MAC                      0x10000
-#define TASK_FEATURE_L3                                0x20000
 
 #define FLAG_TX_FLUSH                  0x01
 #define FLAG_NEVER_FLUSH               0x02
index 3af0db2..2bc83f3 100644 (file)
@@ -174,7 +174,7 @@ static size_t init_rx_tx_rings_ports(struct task_args *targ, struct task_base *t
        }
        else {
                if (targ->nb_rxports == 1) {
-                       if (targ->task_init->flag_features & TASK_FEATURE_L3)
+                       if (targ->flags & TASK_ARG_L3)
                                tbase->rx_pkt = (targ->task_init->flag_features & TASK_FEATURE_MULTI_RX)? rx_pkt_hw1_multi_l3 : rx_pkt_hw1_l3;
                        else
                                tbase->rx_pkt = (targ->task_init->flag_features & TASK_FEATURE_MULTI_RX)? rx_pkt_hw1_multi : rx_pkt_hw1;
@@ -183,7 +183,7 @@ static size_t init_rx_tx_rings_ports(struct task_args *targ, struct task_base *t
                }
                else {
                        PROX_ASSERT((targ->nb_rxports != 0) || (targ->task_init->flag_features & TASK_FEATURE_NO_RX));
-                       if (targ->task_init->flag_features & TASK_FEATURE_L3)
+                       if (targ->flags & TASK_ARG_L3)
                                tbase->rx_pkt = (targ->task_init->flag_features & TASK_FEATURE_MULTI_RX)? rx_pkt_hw_multi_l3 : rx_pkt_hw_l3;
                        else
                                tbase->rx_pkt = (targ->task_init->flag_features & TASK_FEATURE_MULTI_RX)? rx_pkt_hw_multi : rx_pkt_hw;
@@ -196,7 +196,7 @@ static size_t init_rx_tx_rings_ports(struct task_args *targ, struct task_base *t
                        }
 
                        if (rte_is_power_of_2(targ->nb_rxports)) {
-                               if (targ->task_init->flag_features & TASK_FEATURE_L3)
+                               if (targ->flags & TASK_ARG_L3)
                                        tbase->rx_pkt = (targ->task_init->flag_features & TASK_FEATURE_MULTI_RX)? rx_pkt_hw_pow2_multi_l3 : rx_pkt_hw_pow2_l3;
                                else
                                        tbase->rx_pkt = (targ->task_init->flag_features & TASK_FEATURE_MULTI_RX)? rx_pkt_hw_pow2_multi : rx_pkt_hw_pow2;
@@ -351,7 +351,7 @@ struct task_base *init_task_struct(struct task_args *targ)
        tbase->aux = (struct task_base_aux *)(((uint8_t *)tbase) + offset);
 
        if ((targ->nb_txrings != 0) || (targ->nb_txports != 0)) {
-               if (targ->task_init->flag_features & TASK_FEATURE_L3) {
+               if (targ->flags & TASK_ARG_L3) {
                        tbase->aux->tx_pkt_l2 = tbase->tx_pkt;
                        tbase->tx_pkt = tx_pkt_l3;
                }
@@ -369,12 +369,12 @@ struct task_base *init_task_struct(struct task_args *targ)
 
        tbase->handle_bulk = t->handle;
 
-       if (targ->task_init->flag_features & TASK_FEATURE_L3) {
+       if (targ->flags & TASK_ARG_L3) {
                plog_info("\tTask configured in L3 mode\n");
                tbase->l3.ctrl_plane_ring = targ->ctrl_plane_ring;
        }
        if ((targ->nb_txrings != 0) || (targ->nb_txports != 0)) {
-               if (targ->task_init->flag_features & TASK_FEATURE_L3)
+               if (targ->flags & TASK_ARG_L3)
                        task_init_l3(tbase, targ);
        }
 
index 86a9521..745a742 100644 (file)
@@ -46,6 +46,9 @@ struct lcore_cfg;
 #define        TASK_ARG_DO_NOT_SET_SRC_MAC 0x200
 #define        TASK_ARG_DO_NOT_SET_DST_MAC 0x400
 #define        TASK_ARG_HW_SRC_MAC     0x800
+#define TASK_ARG_L3            0x1000
+
+#define PROX_MODE_LEN  32
 
 enum protocols {IPV4, ARP, IPV6};
 
@@ -63,8 +66,8 @@ struct task_args;
 
 struct task_init {
        enum task_mode mode;
-       char mode_str[32];
-       char sub_mode_str[32];
+       char mode_str[PROX_MODE_LEN];
+       char sub_mode_str[PROX_MODE_LEN];
        void (*early_init)(struct task_args *targ);
        void (*init)(struct task_base *tbase, struct task_args *targ);
        int (*handle)(struct task_base *tbase, struct rte_mbuf **mbufs, const uint16_t n_pkts);
@@ -227,6 +230,7 @@ struct task_args {
        struct rte_ring                 **ctrl_tx_rings;
        int                             n_ctrl_rings;
        struct task_base *tmaster;
+       char sub_mode_str[PROX_MODE_LEN];
 };
 
 /* Return the first port that is reachable through the task. If the