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)
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)
{
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);
}
}
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");
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;
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;
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;
}
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;
}
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;
}
#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
}
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;
}
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;
}
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;
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;
}
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);
}
#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};
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);
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