Hybrid Parser
Hydra allows users to use a custom parser together with the hardware parser, which reduces the coding workload and improves performance.
Prerequisites
Using a hybrid parser should comply with specific syntax requirements, including:
- The user must explicitly invoke the hardware parser hdr_fix_parser at the beginning of the start state block within a custom parser.
- If hdr_fix_parser is explicitly invoked, the second parameter of the outer custom parser must include a member field hdr_fix of the hdr_fix_headers type, and both the field name and field type must comply with specified requirements.
- No parameters are required when invoking hdr_fix_parser, and any provided parameters will be automatically ignored.
- Hydra does not support any other form of nested parser calls.
Parsing Mode
When you use a hybrid parser, the hardware parser parses some packet headers, after which you continue the parsing process from the remaining data. To help you in tracking the parsing progress, the packet_in parameter provides two interfaces:
- layers_e hdr_last_layer_get();
Returns the layer of the final packet header parsed by the hardware parser. The return value is defined by the layers_e enumeration.
- bit<16> hdr_last_layer_type_get();
Returns the protocol type of the final packet header parsed by the hardware parser. The return value is a bit<16> unsigned integer.
You can leverage the return values from these two interfaces to determine the appropriate transition for subsequent parsing.
Example
The following is an example of using a hybrid parser. For details about the functions, see the BeiMing 26.0.RC1 FlexDA Programming Framework API Reference.
struct my_headers {
hdr_fix_headers hdr_fix;
l3_union_t inner_l3;
l4_union_t inner_l4;
}
parser my_parser(packet_in packet, out my_headers hdr) {
state start {
hdr_fix_parser();
transition parse_1;
}
state parse_1 {
layers_e layer = packet.hdr_last_layer_get();
transition select(layer) {
layers_e.inner_l2 : parse_inner_l2;
default : accept;
}
}
state parse_inner_l2 {
packet.extract(hdr.hdr_fix.inner_l2, TYPE_ETH, layers_e.inner_l2);
/* ... */
}
}
RX_OVS(
my_parser(),
MyPrePipe(),
MyPostPipe()
) main;