action vxlan_encap args instanceof vxlan_encap_args_t {
//Set the outer Ethernet header.
+ validate h.outer_ethernet
mov h.outer_ethernet.dst_addr t.ethernet_dst_addr
mov h.outer_ethernet.src_addr t.ethernet_src_addr
mov h.outer_ethernet.ethertype t.ethernet_ethertype
- validate h.outer_ethernet
//Set the outer IPv4 header.
+ validate h.outer_ipv4
mov h.outer_ipv4.ver_ihl t.ipv4_ver_ihl
mov h.outer_ipv4.diffserv t.ipv4_diffserv
mov h.outer_ipv4.total_len t.ipv4_total_len
mov h.outer_ipv4.hdr_checksum t.ipv4_hdr_checksum
mov h.outer_ipv4.src_addr t.ipv4_src_addr
mov h.outer_ipv4.dst_addr t.ipv4_dst_addr
- validate h.outer_ipv4
//Set the outer UDP header.
+ validate h.outer_udp
mov h.outer_udp.src_port t.udp_src_port
mov h.outer_udp.dst_port t.udp_dst_port
mov h.outer_udp.length t.udp_length
mov h.outer_udp.checksum t.udp_checksum
- validate h.outer_udp
//Set the outer VXLAN header.
+ validate h.outer_vxlan
mov h.outer_vxlan.flags t.vxlan_flags
mov h.outer_vxlan.reserved t.vxlan_reserved
mov h.outer_vxlan.vni t.vxlan_vni
mov h.outer_vxlan.reserved2 t.vxlan_reserved2
- validate h.outer_vxlan
//Set the output port.
mov m.port_out t.port_out
instr->type = INSTR_HDR_VALIDATE;
instr->valid.header_id = h->id;
+ instr->valid.struct_id = h->struct_id;
return 0;
}
uint32_t n_instructions);
static int
-instr_pattern_mov_all_validate_search(struct rte_swx_pipeline *p,
+instr_pattern_validate_mov_all_search(struct rte_swx_pipeline *p,
struct action *a,
struct instruction *instr,
struct instruction_data *data,
if (!a || !a->st)
return 0;
- /* First instruction: MOV_HM. */
- if (data[0].invalid || (instr[0].type != INSTR_MOV_HM))
+ /* First instruction: HDR_VALIDATE. Second instruction: MOV_HM. */
+ if (data[0].invalid ||
+ (instr[0].type != INSTR_HDR_VALIDATE) ||
+ (n_instr < 2) ||
+ data[1].invalid ||
+ (instr[1].type != INSTR_MOV_HM) ||
+ instr[1].mov.src.struct_id)
return 0;
- h = header_find_by_struct_id(p, instr[0].mov.dst.struct_id);
- if (!h || h->st->var_size)
+ h = header_find_by_struct_id(p, instr[0].valid.struct_id);
+ if (!h ||
+ h->st->var_size ||
+ (n_instr < 1 + h->st->n_fields))
return 0;
for (src_field_id = 0; src_field_id < a->st->n_fields; src_field_id++)
- if (instr[0].mov.src.offset == a->st->fields[src_field_id].offset / 8)
+ if (instr[1].mov.src.offset == a->st->fields[src_field_id].offset / 8)
break;
- if (src_field_id == a->st->n_fields)
+ if (src_field_id + h->st->n_fields > a->st->n_fields)
return 0;
- if (instr[0].mov.dst.offset ||
- (instr[0].mov.dst.n_bits != h->st->fields[0].n_bits) ||
- instr[0].mov.src.struct_id ||
- (instr[0].mov.src.n_bits != a->st->fields[src_field_id].n_bits) ||
- (instr[0].mov.dst.n_bits != instr[0].mov.src.n_bits))
- return 0;
-
- if ((n_instr < h->st->n_fields + 1) ||
- (a->st->n_fields < src_field_id + h->st->n_fields + 1))
- return 0;
-
- /* Subsequent instructions: MOV_HM. */
- for (i = 1; i < h->st->n_fields; i++)
- if (data[i].invalid ||
- data[i].n_users ||
- (instr[i].type != INSTR_MOV_HM) ||
- (instr[i].mov.dst.struct_id != h->struct_id) ||
- (instr[i].mov.dst.offset != h->st->fields[i].offset / 8) ||
- (instr[i].mov.dst.n_bits != h->st->fields[i].n_bits) ||
- instr[i].mov.src.struct_id ||
- (instr[i].mov.src.offset != a->st->fields[src_field_id + i].offset / 8) ||
- (instr[i].mov.src.n_bits != a->st->fields[src_field_id + i].n_bits) ||
- (instr[i].mov.dst.n_bits != instr[i].mov.src.n_bits))
+ /* Second and subsequent instructions: MOV_HM. */
+ for (i = 0; i < h->st->n_fields; i++)
+ if (data[1 + i].invalid ||
+ data[1 + i].n_users ||
+ (instr[1 + i].type != INSTR_MOV_HM) ||
+ (instr[1 + i].mov.dst.struct_id != h->struct_id) ||
+ (instr[1 + i].mov.dst.offset != h->st->fields[i].offset / 8) ||
+ (instr[1 + i].mov.dst.n_bits != h->st->fields[i].n_bits) ||
+ instr[1 + i].mov.src.struct_id ||
+ (instr[1 + i].mov.src.offset != a->st->fields[src_field_id + i].offset / 8) ||
+ (instr[1 + i].mov.src.n_bits != a->st->fields[src_field_id + i].n_bits) ||
+ (instr[1 + i].mov.dst.n_bits != instr[1 + i].mov.src.n_bits))
return 0;
- /* Last instruction: HDR_VALIDATE. */
- if ((instr[i].type != INSTR_HDR_VALIDATE) ||
- (instr[i].valid.header_id != h->id))
- return 0;
-
/* Check that none of the action args that are used as source for this
* DMA transfer are not used as source in any other mov instruction.
*/
return 0;
}
- *n_pattern_instr = 1 + i;
+ *n_pattern_instr = 1 + h->st->n_fields;
return 1;
}
static void
-instr_pattern_mov_all_validate_replace(struct rte_swx_pipeline *p,
+instr_pattern_validate_mov_all_replace(struct rte_swx_pipeline *p,
struct action *a,
struct instruction *instr,
struct instruction_data *data,
uint32_t src_field_id, src_offset, i;
/* Read from the instructions before they are modified. */
- h = header_find_by_struct_id(p, instr[0].mov.dst.struct_id);
+ h = header_find_by_struct_id(p, instr[1].mov.dst.struct_id);
if (!h)
return;
+ src_offset = instr[1].mov.src.offset;
+
for (src_field_id = 0; src_field_id < a->st->n_fields; src_field_id++)
- if (instr[0].mov.src.offset == a->st->fields[src_field_id].offset / 8)
+ if (src_offset == a->st->fields[src_field_id].offset / 8)
break;
- if (src_field_id == a->st->n_fields)
- return;
-
- src_offset = instr[0].mov.src.offset;
-
/* Modify the instructions. */
instr[0].type = INSTR_DMA_HT;
instr[0].dma.dst.header_id[0] = h->id;
}
static uint32_t
-instr_pattern_mov_all_validate_optimize(struct rte_swx_pipeline *p,
+instr_pattern_validate_mov_all_optimize(struct rte_swx_pipeline *p,
struct action *a,
struct instruction *instructions,
struct instruction_data *instruction_data,
uint32_t n_instr = 0;
int detected;
- /* Mov all + validate. */
- detected = instr_pattern_mov_all_validate_search(p,
+ /* Validate + mov all. */
+ detected = instr_pattern_validate_mov_all_search(p,
a,
instr,
data,
n_instructions,
&n_instr);
if (detected) {
- instr_pattern_mov_all_validate_replace(p, a, instr, data, n_instr);
+ instr_pattern_validate_mov_all_replace(p, a, instr, data, n_instr);
i += n_instr;
continue;
}
instruction_data,
n_instructions);
- /* Mov all + validate. */
- n_instructions = instr_pattern_mov_all_validate_optimize(p,
+ /* Validate + mov all. */
+ n_instructions = instr_pattern_validate_mov_all_optimize(p,
a,
instructions,
instruction_data,