[P4-dev] VL field bitwidth needs to be a multiple of 8

Regis Martins regisftm at gmail.com
Wed Jul 19 21:34:27 EDT 2017


Hi Antonin,

Here is what I found in the .json:

          "expression" : {
            "type" : "expression",
            "value" : {
              "op" : "and",
              "left" : {
                "type" : "expression",
                "value" : {
                  "op" : "==",
                  "left" : {
                    "type" : "field",
                    *"value" : ["ipv4", "$valid$"]*
                  },
                  "right" : {
                    "type" : "hexstr",
                    "value" : "0x01"
                  }
                }
              },
              "right" : {
                "type" : "expression",
                "value" : {
                  "op" : ">",
                  "left" : {
                    "type" : "field",
                    "value" : ["ipv4", "ttl"]
                  },
                  "right" : {
                    "type" : "hexstr",
                    "value" : "0x00"


I'm using P4C to generate it with the following params:

/usr/local/bin/p4c --target bmv2-ss-p4org -x p4-14 p4src/task_9.p4 -o p4prog

I'm not sure how to change it exactly...

​Thank you,

*Regis Martins*


On Wed, Jul 19, 2017 at 10:16 PM, Antonin Bas <antonin at barefootnetworks.com>
wrote:

> That looks like another issue with the generated JSON. Each header has a
> $valid$ field added by the compiler which can be read to check if a header
> is valid. However, this is a read-only field. Here the JSON code tries to
> set that field to 1 to make the ipv4 header valid, but because the field is
> read-only, it has no effect. The ipv4 header is therefore not considered
> valid. The bmv2 implementation evaluates invalid fields as "00...0" in
> table lookups, which explains the logs that you are seeing (and also why
> the checksum verification is skipped).
>
> I suggest that you open an issue on p4lang/p4c describing this issue.
>
> I have yet another workaround for you but it requires you to modify the
> JSON file by hand :)
>
> Locate the following:
>             {
>               "parameters" : [
>                 {
>                   "type" : "field",
>                   "value" : ["ipv4", "$valid$"]
>                 },
>                 {
>                   "type" : "expression",
>                   "value" : {
>                     "type" : "expression",
>                     "value" : {
>                       "op" : "b2d",
>                       "left" : null,
>                       "right" : {
>                         "type" : "bool",
>                         "value" : true
>                       }
>                     }
>                   }
>                 }
>               ],
>               "op" : "set"
>             }
>
> And replace it with:
>             {
>               "parameters" : [
>                 {
>                   "op" : "add_header",
>                   "parameters" : [{"type" : "header", "value" : "ipv4"}]
>                 }
>               ],
>               "op" : "primitive"
>             }
>
> Assuming I didn't make a typo, it should work.
>
> On Wed, Jul 19, 2017 at 5:49 PM, Regis Martins <regisftm at gmail.com> wrote:
>
>> ​Hello Antonin,
>>
>> I just tried that...
>>
>> Here is the output:
>>
>> [21:31:05.731] [bmv2] [D] [thread 7478] [33.0] [cxt 0] Processing packet
>> received on port 1
>> [21:31:05.731] [bmv2] [D] [thread 7478] [33.0] [cxt 0] Parser 'parser':
>> start
>> [21:31:05.731] [bmv2] [D] [thread 7478] [33.0] [cxt 0] Parser state
>> 'start' has no switch, going to default next state
>> [21:31:05.731] [bmv2] [T] [thread 7478] [33.0] [cxt 0] Bytes parsed: 0
>> [21:31:05.731] [bmv2] [D] [thread 7478] [33.0] [cxt 0] Extracting header
>> 'eth'
>> [21:31:05.731] [bmv2] [D] [thread 7478] [33.0] [cxt 0] Parser state
>> 'parse_eth': key is 0800
>> [21:31:05.731] [bmv2] [T] [thread 7478] [33.0] [cxt 0] Bytes parsed: 14
>> [21:31:05.731] [bmv2] [D] [thread 7478] [33.0] [cxt 0] Extracting header
>> 'tmp_hdr'
>> [21:31:05.731] [bmv2] [D] [thread 7478] [33.0] [cxt 0] Parser set:
>> setting field 'scalars.tmp' from expression, new value is 0
>> [21:31:05.731] [bmv2] [D] [thread 7478] [33.0] [cxt 0] Extracting
>> variable-sized header 'tmp_hdr_0'
>> [21:31:05.731] [bmv2] [D] [thread 7478] [33.0] [cxt 0] Parser set:
>> setting field 'ipv4.$valid$' from expression, new value is 1
>> [21:31:05.731] [bmv2] [D] [thread 7478] [33.0] [cxt 0] Parser set:
>> setting field 'ipv4.version' from field 'tmp_hdr.version' (4)
>> [21:31:05.731] [bmv2] [D] [thread 7478] [33.0] [cxt 0] Parser set:
>> setting field 'ipv4.ihl' from field 'tmp_hdr.ihl' (5)
>> [21:31:05.731] [bmv2] [D] [thread 7478] [33.0] [cxt 0] Parser set:
>> setting field 'ipv4.diffserv' from field 'tmp_hdr.diffserv' (0)
>> [21:31:05.731] [bmv2] [D] [thread 7478] [33.0] [cxt 0] Parser set:
>> setting field 'ipv4.totalLen' from field 'tmp_hdr.totalLen' (84)
>> [21:31:05.731] [bmv2] [D] [thread 7478] [33.0] [cxt 0] Parser set:
>> setting field 'ipv4.id' from field 'tmp_hdr.id' (58185)
>> [21:31:05.731] [bmv2] [D] [thread 7478] [33.0] [cxt 0] Parser set:
>> setting field 'ipv4.flags' from field 'tmp_hdr.flags' (2)
>> [21:31:05.731] [bmv2] [D] [thread 7478] [33.0] [cxt 0] Parser set:
>> setting field 'ipv4.fragOffset' from field 'tmp_hdr.fragOffset' (0)
>> [21:31:05.731] [bmv2] [D] [thread 7478] [33.0] [cxt 0] Parser set:
>> setting field 'ipv4.ttl' from field 'tmp_hdr.ttl' (64)
>> [21:31:05.731] [bmv2] [D] [thread 7478] [33.0] [cxt 0] Parser set:
>> setting field 'ipv4.protocol' from field 'tmp_hdr.protocol' (1)
>> [21:31:05.731] [bmv2] [D] [thread 7478] [33.0] [cxt 0] Parser set:
>> setting field 'ipv4.hdrChecksum' from field 'tmp_hdr.hdrChecksum' (16972)
>> [21:31:05.731] [bmv2] [D] [thread 7478] [33.0] [cxt 0] *Parser set:
>> setting field 'ipv4.srcAddr' from field 'tmp_hdr.srcAddr' (167772170)*
>> [21:31:05.731] [bmv2] [D] [thread 7478] [33.0] [cxt 0] Parser set:
>> setting field 'ipv4.dstAddr' from field 'tmp_hdr.dstAddr' (167772426)
>> [21:31:05.731] [bmv2] [D] [thread 7478] [33.0] [cxt 0] Parser set:
>> setting field 'ipv4.options_ipv4' from field 'tmp_hdr_0.options_ipv4' (0)
>> [21:31:05.731] [bmv2] [D] [thread 7478] [33.0] [cxt 0] Parser state
>> 'parse_ipv4': key is 01
>> [21:31:05.731] [bmv2] [T] [thread 7478] [33.0] [cxt 0] Bytes parsed: 34
>> [21:31:05.731] [bmv2] [D] [thread 7478] [33.0] [cxt 0] Extracting header
>> 'icmp'
>> [21:31:05.731] [bmv2] [D] [thread 7478] [33.0] [cxt 0] Parser state
>> 'parse_icmp' has no switch, going to default next state
>> [21:31:05.731] [bmv2] [T] [thread 7478] [33.0] [cxt 0] Bytes parsed: 38
>> [21:31:05.731] [bmv2] [D] [thread 7478] [33.0] [cxt 0] Extracting header
>> 'payld'
>> [21:31:05.731] [bmv2] [D] [thread 7478] [33.0] [cxt 0] Parser state
>> 'parse_payld' has no switch, going to default next state
>> [21:31:05.731] [bmv2] [T] [thread 7478] [33.0] [cxt 0] Bytes parsed: 46
>> [21:31:05.731] [bmv2] [T] [thread 7478] [33.0] [cxt 0] Skipping checksum
>> 'cksum' verification because target field invalid
>> [21:31:05.731] [bmv2] [D] [thread 7478] [33.0] [cxt 0] Parser 'parser':
>> end
>> [21:31:05.731] [bmv2] [D] [thread 7478] [33.0] [cxt 0] Pipeline
>> 'ingress': start
>> [21:31:05.731] [bmv2] [T] [thread 7478] [33.0] [cxt 0]
>> p4src/task_9.p4(201) Condition "and" is true
>> [21:31:05.731] [bmv2] [T] [thread 7478] [33.0] [cxt 0] Applying table
>> 'set_table'
>> [21:31:05.731] [bmv2] [D] [thread 7478] [33.0] [cxt 0] Looking up key:
>> ** ipv4.srcAddr        : 00000000 *
>>
>>
>> ​For some weird reason, set field is not working for ipv4.srcAddr... that
>> should be * ipv4.srcAddr        : 0a00000a
>>
>> If I remove the options_ipv4 field and the length and max_length
>> parameters it works fine...
>>
>> Any other advice?
>>
>> Thank you,
>>
>>
>> *Regis Martins*
>>
>>
>> On Wed, Jul 19, 2017 at 8:06 PM, Regis Martins <regisftm at gmail.com>
>> wrote:
>>
>>> Got it!
>>>
>>> Let me test it.
>>>
>>> Thanks again Antonin! You will have a note of thanks on my thesis! :)
>>>
>>> Regards,
>>>
>>> *Regis Martins*
>>>
>>>
>>> On Wed, Jul 19, 2017 at 7:59 PM, Antonin Bas <
>>> antonin at barefootnetworks.com> wrote:
>>>
>>>> Looks like a p4c-bm2-ss compiler bug to me. I opened a Github issue:
>>>> https://github.com/p4lang/p4c/issues/781
>>>> Your P4 program is correct, but the generated bmv2 JSON is not. As a
>>>> workaround (while waiting for the issue to be fixed), you may be able to
>>>> replace (ihl << 2) with ((ihl << 2) - 20) * 8. This is no longer correct
>>>> P4, but will leverage the p4c-bm2-ss bug to get your program running on
>>>> bmv2.
>>>>
>>>> On Wed, Jul 19, 2017 at 3:18 PM, Regis Martins <regisftm at gmail.com>
>>>> wrote:
>>>>
>>>>> Hello people!
>>>>>
>>>>> I'm trying to create a variable length field on my ipv4 header, as
>>>>> following:
>>>>>
>>>>> ...
>>>>>
>>>>> header_type ipv4_t {
>>>>>     fields {
>>>>>         version     : 4;
>>>>>         ihl         : 4;
>>>>>         diffserv    : 8;
>>>>>         totalLen    : 16;
>>>>>         id          : 16;
>>>>>         flags       : 3;
>>>>>         fragOffset  : 13;
>>>>>         ttl         : 8;
>>>>>         protocol    : 8;
>>>>>         hdrChecksum : 16;
>>>>>         srcAddr     : 32;
>>>>>         dstAddr     : 32;
>>>>>         options_ipv4: *;
>>>>>     }
>>>>>     length          : (ihl << 2);
>>>>>     max_length      : 60;
>>>>> }
>>>>>
>>>>>
>>>>> ...
>>>>>
>>>>>
>>>>> The compilation works fine, however the fist packet_in (it is a ping),
>>>>> abends the bmv2 with the following message:
>>>>>
>>>>> [19:05:52.601] [bmv2] [D] [thread 6991] [33.0] [cxt 0] Parser
>>>>> 'parser': start
>>>>> [19:05:52.601] [bmv2] [D] [thread 6991] [33.0] [cxt 0] Parser state
>>>>> 'start' has no switch, going to default next state
>>>>> [19:05:52.601] [bmv2] [T] [thread 6991] [33.0] [cxt 0] Bytes parsed: 0
>>>>> [19:05:52.601] [bmv2] [D] [thread 6991] [33.0] [cxt 0] Extracting
>>>>> header 'eth'
>>>>> [19:05:52.601] [bmv2] [D] [thread 6991] [33.0] [cxt 0] Parser state
>>>>> 'parse_eth': key is 0800
>>>>> [19:05:52.601] [bmv2] [T] [thread 6991] [33.0] [cxt 0] Bytes parsed: 14
>>>>> [19:05:52.601] [bmv2] [D] [thread 6991] [33.0] [cxt 0] Extracting
>>>>> header 'tmp_hdr'
>>>>> [19:05:52.601] [bmv2] [D] [thread 6991] [33.0] [cxt 0] Parser set:
>>>>> setting field 'scalars.tmp' from expression, new value is 4
>>>>> *[19:05:52.601] [bmv2] [D] [thread 6991] [33.0] [cxt 0] Extracting
>>>>> variable-sized header 'tmp_hdr_0'*
>>>>> *simple_switch: parser.cpp:288: virtual void
>>>>> bm::ParserOpExtractVL::operator()(bm::Packet*, const char*, size_t*) const:
>>>>> Assertion `nbits % 8 == 0 && "VL field bitwidth needs to be a multiple of
>>>>> 8"' failed.*
>>>>>
>>>>> Any clue about what is happening?
>>>>>
>>>>> Please, let me know if there you need further information...
>>>>>
>>>>> Regards,
>>>>>
>>>>> *Regis Martins*
>>>>>
>>>>> _______________________________________________
>>>>> P4-dev mailing list
>>>>> P4-dev at lists.p4.org
>>>>> http://lists.p4.org/mailman/listinfo/p4-dev_lists.p4.org
>>>>>
>>>>
>>>>
>>>>
>>>> --
>>>> Antonin
>>>>
>>>
>>>
>>
>
>
> --
> Antonin
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.p4.org/pipermail/p4-dev_lists.p4.org/attachments/20170719/ca9a3ae6/attachment-0002.html>


More information about the P4-dev mailing list