X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=lib%2Fpipeline%2Frte_swx_pipeline.c;h=8c4670e11172283fdc76b50dbcebf652e7510646;hb=77e764c7ecd36de92c574731d05d1fb34c28e680;hp=2145ca0a427e1606bdf878e716398b0e0e834db5;hpb=54abd300d582f67367ae385d37d6e60d2a6d8b96;p=dpdk.git diff --git a/lib/pipeline/rte_swx_pipeline.c b/lib/pipeline/rte_swx_pipeline.c index 2145ca0a42..8c4670e111 100644 --- a/lib/pipeline/rte_swx_pipeline.c +++ b/lib/pipeline/rte_swx_pipeline.c @@ -4,9 +4,16 @@ #include #include #include -#include #include +#include +#include +#include +#include "rte_swx_port_source_sink.h" + +#include +#include + #include "rte_swx_pipeline_internal.h" #define CHECK(condition, err_code) \ @@ -1370,6 +1377,7 @@ instruction_is_tx(enum instruction_type type) switch (type) { case INSTR_TX: case INSTR_TX_I: + case INSTR_DROP: return 1; default: @@ -1383,6 +1391,7 @@ instruction_does_tx(struct instruction *instr) switch (instr->type) { case INSTR_TX: case INSTR_TX_I: + case INSTR_DROP: case INSTR_HDR_EMIT_TX: case INSTR_HDR_EMIT2_TX: case INSTR_HDR_EMIT3_TX: @@ -1591,7 +1600,7 @@ instr_tx_translate(struct rte_swx_pipeline *p, } static int -instr_drop_translate(struct rte_swx_pipeline *p, +instr_drop_translate(struct rte_swx_pipeline *p __rte_unused, struct action *action __rte_unused, char **tokens __rte_unused, int n_tokens, @@ -1600,9 +1609,8 @@ instr_drop_translate(struct rte_swx_pipeline *p, { CHECK(n_tokens == 1, EINVAL); - /* TX_I. */ - instr->type = INSTR_TX_I; - instr->io.io.val = p->n_ports_out - 1; + /* DROP. */ + instr->type = INSTR_DROP; return 0; } @@ -1632,6 +1640,19 @@ instr_tx_i_exec(struct rte_swx_pipeline *p) instr_rx_exec(p); } +static inline void +instr_drop_exec(struct rte_swx_pipeline *p) +{ + struct thread *t = &p->threads[p->thread_id]; + struct instruction *ip = t->ip; + + __instr_drop_exec(p, t, ip); + + /* Thread. */ + thread_ip_reset(p, t); + instr_rx_exec(p); +} + /* * extract. */ @@ -2865,8 +2886,8 @@ instr_alu_ckadd_translate(struct rte_swx_pipeline *p, CHECK(n_tokens == 3, EINVAL); fdst = header_field_parse(p, dst, &hdst); - CHECK(fdst && (fdst->n_bits == 16), EINVAL); - CHECK(!fdst->var_size, EINVAL); + CHECK(fdst, EINVAL); + CHECK(!fdst->var_size && (fdst->n_bits == 16), EINVAL); /* CKADD_FIELD. */ fsrc = header_field_parse(p, src, &hsrc); @@ -2886,17 +2907,16 @@ instr_alu_ckadd_translate(struct rte_swx_pipeline *p, /* CKADD_STRUCT, CKADD_STRUCT20. */ hsrc = header_parse(p, src); CHECK(hsrc, EINVAL); - CHECK(!hsrc->st->var_size, EINVAL); instr->type = INSTR_ALU_CKADD_STRUCT; - if ((hsrc->st->n_bits / 8) == 20) + if (!hsrc->st->var_size && ((hsrc->st->n_bits / 8) == 20)) instr->type = INSTR_ALU_CKADD_STRUCT20; instr->alu.dst.struct_id = (uint8_t)hdst->struct_id; instr->alu.dst.n_bits = fdst->n_bits; instr->alu.dst.offset = fdst->offset / 8; instr->alu.src.struct_id = (uint8_t)hsrc->struct_id; - instr->alu.src.n_bits = hsrc->st->n_bits; + instr->alu.src.n_bits = (uint8_t)hsrc->id; /* The src header ID is stored here. */ instr->alu.src.offset = 0; /* Unused. */ return 0; } @@ -2916,8 +2936,8 @@ instr_alu_cksub_translate(struct rte_swx_pipeline *p, CHECK(n_tokens == 3, EINVAL); fdst = header_field_parse(p, dst, &hdst); - CHECK(fdst && (fdst->n_bits == 16), EINVAL); - CHECK(!fdst->var_size, EINVAL); + CHECK(fdst, EINVAL); + CHECK(!fdst->var_size && (fdst->n_bits == 16), EINVAL); fsrc = header_field_parse(p, src, &hsrc); CHECK(fsrc, EINVAL); @@ -5978,6 +5998,19 @@ instr_label_check(struct instruction_data *instruction_data, CHECK(strcmp(label, instruction_data[j].label), EINVAL); } + /* Check that no jump instruction (either conditional or not) can jump to itself (loop). */ + for (i = 0; i < n_instructions; i++) { + struct instruction_data *data = &instruction_data[i]; + char *label = data->label; + char *jmp_label = data->jmp_label; + + /* Continue if this instruction does not have a label or it is not a jump. */ + if (!label[0] || !jmp_label[0]) + continue; + + CHECK(strcmp(label, jmp_label), EINVAL); + } + /* Get users for each instruction label. */ for (i = 0; i < n_instructions; i++) { struct instruction_data *data = &instruction_data[i]; @@ -6199,7 +6232,7 @@ instr_pattern_emit_many_tx_search(struct instruction *instr, if (!i) return 0; - if (!instruction_is_tx(instr[i].type)) + if (instr[i].type != INSTR_TX) return 0; if (data[i].n_users) @@ -6643,6 +6676,7 @@ static instr_exec_t instruction_table[] = { [INSTR_RX] = instr_rx_exec, [INSTR_TX] = instr_tx_exec, [INSTR_TX_I] = instr_tx_i_exec, + [INSTR_DROP] = instr_drop_exec, [INSTR_HDR_EXTRACT] = instr_hdr_extract_exec, [INSTR_HDR_EXTRACT2] = instr_hdr_extract2_exec, @@ -8531,7 +8565,7 @@ table_state_build(struct rte_swx_pipeline *p) struct selector *s; struct learner *l; - p->table_state = calloc(p->n_tables + p->n_selectors, + p->table_state = calloc(p->n_tables + p->n_selectors + p->n_learners, sizeof(struct rte_swx_table_state)); CHECK(p->table_state, ENOMEM); @@ -8967,17 +9001,144 @@ metarray_free(struct rte_swx_pipeline *p) /* * Pipeline. */ +void +rte_swx_pipeline_free(struct rte_swx_pipeline *p) +{ + void *lib; + + if (!p) + return; + + lib = p->lib; + + free(p->instruction_data); + free(p->instructions); + + metarray_free(p); + regarray_free(p); + table_state_free(p); + learner_free(p); + selector_free(p); + table_free(p); + action_free(p); + instruction_table_free(p); + metadata_free(p); + header_free(p); + extern_func_free(p); + extern_obj_free(p); + port_out_free(p); + port_in_free(p); + struct_free(p); + + free(p); + + if (lib) + dlclose(lib); +} + +static int +port_in_types_register(struct rte_swx_pipeline *p) +{ + int status; + + status = rte_swx_pipeline_port_in_type_register(p, + "ethdev", + &rte_swx_port_ethdev_reader_ops); + if (status) + return status; + + status = rte_swx_pipeline_port_in_type_register(p, + "ring", + &rte_swx_port_ring_reader_ops); + if (status) + return status; + +#ifdef RTE_PORT_PCAP + status = rte_swx_pipeline_port_in_type_register(p, + "source", + &rte_swx_port_source_ops); + if (status) + return status; +#endif + + status = rte_swx_pipeline_port_in_type_register(p, + "fd", + &rte_swx_port_fd_reader_ops); + if (status) + return status; + + return 0; +} + +static int +port_out_types_register(struct rte_swx_pipeline *p) +{ + int status; + + status = rte_swx_pipeline_port_out_type_register(p, + "ethdev", + &rte_swx_port_ethdev_writer_ops); + if (status) + return status; + + status = rte_swx_pipeline_port_out_type_register(p, + "ring", + &rte_swx_port_ring_writer_ops); + if (status) + return status; + + status = rte_swx_pipeline_port_out_type_register(p, + "sink", + &rte_swx_port_sink_ops); + if (status) + return status; + + status = rte_swx_pipeline_port_out_type_register(p, + "fd", + &rte_swx_port_fd_writer_ops); + if (status) + return status; + + return 0; +} + +static int +table_types_register(struct rte_swx_pipeline *p) +{ + int status; + + status = rte_swx_pipeline_table_type_register(p, + "exact", + RTE_SWX_TABLE_MATCH_EXACT, + &rte_swx_table_exact_match_ops); + if (status) + return status; + + status = rte_swx_pipeline_table_type_register(p, + "wildcard", + RTE_SWX_TABLE_MATCH_WILDCARD, + &rte_swx_table_wildcard_match_ops); + if (status) + return status; + + return 0; +} + int rte_swx_pipeline_config(struct rte_swx_pipeline **p, int numa_node) { - struct rte_swx_pipeline *pipeline; + struct rte_swx_pipeline *pipeline = NULL; + int status = 0; /* Check input parameters. */ CHECK(p, EINVAL); /* Memory allocation. */ pipeline = calloc(1, sizeof(struct rte_swx_pipeline)); - CHECK(pipeline, ENOMEM); + if (!pipeline) { + status = -ENOMEM; + goto error; + } /* Initialization. */ TAILQ_INIT(&pipeline->struct_types); @@ -9001,43 +9162,24 @@ rte_swx_pipeline_config(struct rte_swx_pipeline **p, int numa_node) pipeline->n_structs = 1; /* Struct 0 is reserved for action_data. */ pipeline->numa_node = numa_node; - *p = pipeline; - return 0; -} - -void -rte_swx_pipeline_free(struct rte_swx_pipeline *p) -{ - void *lib; - - if (!p) - return; - - lib = p->lib; + status = port_in_types_register(pipeline); + if (status) + goto error; - free(p->instruction_data); - free(p->instructions); + status = port_out_types_register(pipeline); + if (status) + goto error; - metarray_free(p); - regarray_free(p); - table_state_free(p); - learner_free(p); - selector_free(p); - table_free(p); - action_free(p); - instruction_table_free(p); - metadata_free(p); - header_free(p); - extern_func_free(p); - extern_obj_free(p); - port_out_free(p); - port_in_free(p); - struct_free(p); + status = table_types_register(pipeline); + if (status) + goto error; - free(p); + *p = pipeline; + return 0; - if (lib) - dlclose(lib); +error: + rte_swx_pipeline_free(pipeline); + return status; } int @@ -9068,6 +9210,9 @@ pipeline_compile(struct rte_swx_pipeline *p); int rte_swx_pipeline_build(struct rte_swx_pipeline *p) { + struct rte_swx_port_sink_params drop_port_params = { + .file_name = NULL, + }; int status; CHECK(p, EINVAL); @@ -9077,6 +9222,14 @@ rte_swx_pipeline_build(struct rte_swx_pipeline *p) if (status) goto error; + /* Drop port. */ + status = rte_swx_pipeline_port_out_config(p, + p->n_ports_out, + "sink", + &drop_port_params); + if (status) + goto error; + status = port_out_build(p); if (status) goto error; @@ -9901,6 +10054,7 @@ instr_type_to_name(struct instruction *instr) case INSTR_TX: return "INSTR_TX"; case INSTR_TX_I: return "INSTR_TX_I"; + case INSTR_DROP: return "INSTR_DROP"; case INSTR_HDR_EXTRACT: return "INSTR_HDR_EXTRACT"; case INSTR_HDR_EXTRACT2: return "INSTR_HDR_EXTRACT2"; @@ -10126,8 +10280,9 @@ instr_io_export(struct instruction *instr, FILE *f) instr_type_to_name(instr)); /* instr.io. */ - fprintf(f, - "\t\t.io = {\n"); + if (n_io || n_io_imm || n_hdrs) + fprintf(f, + "\t\t.io = {\n"); /* instr.io.io. */ if (n_io) @@ -10193,8 +10348,9 @@ instr_io_export(struct instruction *instr, FILE *f) } /* instr.io - closing curly brace. */ - fprintf(f, - "\t\t},\n"); + if (n_io || n_io_imm || n_hdrs) + fprintf(f, + "\t\t},\n"); /* instr - closing curly brace. */ fprintf(f, @@ -10767,6 +10923,7 @@ static instruction_export_t export_table[] = { [INSTR_TX] = instr_io_export, [INSTR_TX_I] = instr_io_export, + [INSTR_DROP] = instr_io_export, [INSTR_HDR_EXTRACT] = instr_io_export, [INSTR_HDR_EXTRACT2] = instr_io_export, @@ -10984,6 +11141,7 @@ instr_type_to_func(struct instruction *instr) case INSTR_TX: return "__instr_tx_exec"; case INSTR_TX_I: return "__instr_tx_i_exec"; + case INSTR_DROP: return "__instr_drop_exec"; case INSTR_HDR_EXTRACT: return "__instr_hdr_extract_exec"; case INSTR_HDR_EXTRACT2: return "__instr_hdr_extract2_exec";