Rate This Document
Findability
Accuracy
Completeness
Readability

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;