[P4-dev] Variable length header extraction on header stacks

Joshua Hartmann j.hartmann.1995 at googlemail.com
Thu Dec 21 10:43:58 EST 2017


I'm currently trying to parse LLDP packets,for this i need to parse a
sequence of TLV structures.
After creating the header type of such a TLV i tried to parse the variable
length headers into a header stack. Compiling this works fine, but the
simple switch breaks when trying to start it giving the following error in
the logfile:
*lt-simple_switch: P4Objects.cpp:981: void
bm::P4Objects::init_parsers(const Json::Value&, bm::P4Objects::InitState*):
Assertion `cfg_extract["type"].asString() == "regular"' failed.*
*        packet.extract(hdr.lldp_tlv.next, n * 8);*

Why is it not possible to parse a variable length header in a header stack?

Kind regards,
Josh

Here is the p4 code i used:

/* -*- P4_16 -*- */
#include <core.p4>
#include <v1model.p4>

#define MAX_TLV_COUNT 4

const bit<16> TYPE_LLDP = 0x88CC;

/********************** H E A D E R S ***********************************/
typedef bit<9>  egressSpec_t;
typedef bit<48> macAddr_t;
typedef bit<32> ip4Addr_t;

header ethernet_t {
    macAddr_t dstAddr;
    macAddr_t srcAddr;
    bit<16>   etherType;
}

header lldp_tlv_t {
    bit <7> type;
    bit <9> length;
    varbit<4088> value;
}

header lldp_tlv_helper_t { //used for lookahead in the lldp_tlv parser
    bit<7> type;
    bit<9> length;
}

struct metadata {
}

struct headers {
    ethernet_t   ethernet;
    lldp_tlv_t[MAX_TLV_COUNT] lldp_tlv;
}

/*********************** P A R S E R  ***********************************/
parser MyParser(packet_in packet,
                out headers hdr,
                inout metadata meta,
                inout standard_metadata_t standard_metadata) {
    state start {
        transition parse_ethernet;
    }

    state parse_ethernet {
        packet.extract(hdr.ethernet);
        transition select(hdr.ethernet.etherType) {
            TYPE_LLDP: parse_lldp_tlv;
            default: accept;
        }
    }

    state parse_lldp_tlv {
        bit<32> n = (bit<32>)(packet.lookahead<lldp_tlv_helper_t>().length);
        //will cause the simple switch to crash
        //log entry: lt-simple_switch: P4Objects.cpp:981: void
bm::P4Objects::init_parsers(const Json::Value&, bm::P4Objects::InitState*):
Assertion `cfg_extract["type"].asString() == "regular"' failed.
        packet.extract(hdr.lldp_tlv.next, n * 8);

        //accessing a static index header works fine
        //packet.extract(hdr.lldp_tlv[0], n * 8);
        transition select(hdr.lldp_tlv.last.type) {
            0 : accept; //type 0 indicates end of LLDPDU
            default : parse_lldp_tlv;
        }
    }
}

/***********   C H E C K S U M    V E R I F I C A T I O N   *************/
control MyVerifyChecksum(inout headers hdr, inout metadata meta) {
    apply {  }
}

control MyIngress(inout headers hdr,
                  inout metadata meta,
                  inout standard_metadata_t standard_metadata) {
    apply {
    }
}

/***************  E G R E S S   P R O C E S S I N G   ******************/
control MyEgress(inout headers hdr,
                 inout metadata meta,
                 inout standard_metadata_t standard_metadata) {
    apply {
    }
}

/***********   C H E C K S U M    C O M P U T A T I O N   ***************/
control MyComputeChecksum(inout headers  hdr, inout metadata meta) {
     apply {
     }
}

/**********************  D E P A R S E R  *******************************/
control MyDeparser(packet_out packet, in headers hdr) {
    apply {
        packet.emit(hdr.ethernet);
    }
}

/**********************  S W I T C H  ***********************************/
V1Switch(
    MyParser(),
    MyVerifyChecksum(),
    MyIngress(),
    MyEgress(),
    MyComputeChecksum(),
    MyDeparser()
) main;
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.p4.org/pipermail/p4-dev_lists.p4.org/attachments/20171221/655c62f7/attachment-0002.html>


More information about the P4-dev mailing list