[P4-dev] Bool variable in metadata changes itself

Kuo-Feng Hsu kh42 at rice.edu
Mon Oct 2 15:06:07 EDT 2017


Glad I can help! Thank you for dealing with it!

Sincerely,
Kuo-Feng Hsu

引述 Mihai Budiu <mbudiu at vmware.com>:

> I have filed https://github.com/p4lang/p4c/issues/950 with the  
> compiler. It looks like a bug indeed.
>
> Thank you.
> Mihai
>
> -----Original Message-----
> From: Kuo-Feng Hsu [mailto:kh42 at rice.edu]
> Sent: Thursday, September 28, 2017 11:03 AM
> To: Mihai Budiu <mbudiu at vmware.com>
> Subject: Re: [P4-dev] Bool variable in metadata changes itself
>
> Sure. Here is the log file.
>
> Thanks!
>
> Kuo-Feng Hsu
>
> 引述 Mihai Budiu <mbudiu at vmware.com>:
>
>> Is it possible to also send me the log.txt file?
>> The compiler synthesizes a table with a single default action to set
>> meta.test_bool:
>>
>>     @hidden action act() {
>>         meta.test_bool = false;
>>     }
>>     @hidden table tbl_act {
>>         actions = {
>>             act();
>>         }
>>         const default_action = act();
>>     }
>>     @hidden table tbl_drop {
>>         actions = {
>>             drop_3();
>>         }
>>         const default_action = drop_3();
>>     }
>>     apply {
>>         tbl_act.apply();
>>         if (hdr.ipv4.$valid$ == 1w1)
>>             ipv4_lpm.apply();
>>         if (!meta.test_bool)
>>             tbl_drop.apply();
>>     }
>>
>> It would be interesting to see when this table is executed and whether
>> it properly sets the test_bool field.
>> Mihai
>>
>> -----Original Message-----
>> From: P4-dev [mailto:p4-dev-bounces at lists.p4.org] On Behalf Of
>> Kuo-Feng Hsu
>> Sent: Wednesday, September 27, 2017 6:37 PM
>> To: Andy Fingerhut <andy.fingerhut at gmail.com>
>> Cc: p4-dev <p4-dev at lists.p4.org>
>> Subject: Re: [P4-dev] Bool variable in metadata changes itself
>>
>> Hi Mihai and Andy,
>>
>> Thanks for your advice. The following is the complete code. It's based
>> on the tutorial
>> (https://urldefense.proofpoint.com/v2/url?u=https-3A__github.com_p4lan
>> g_tutorials_tree_master_P4D2-5F2017_exercises_ipv4-5Fforward&d=DwIGaQ&
>> c=uilaK90D4TOVoH58JNXRgQ&r=tGW6TKXajnoXSyy1S1P4DHGPe8sj54GGvw-b21n7aWg
>> &m=TlFd3jODvYr5XzMPVxVOXJ29DPB3wD1yDodBR5kdF7o&s=xAoAje0iGL6G0a4kptGZz
>> vi2E-I8a50Vcy1U9fkdL6E&e=
>> ).
>> Just replace the code in ipv4_forward.p4 in the tutorial with the
>> following code and run the run.sh, and you can see the log result in
>> the build/ipv4_forward.p4.log.
>> You don't have to make any host send any packet. Some packets will be
>> sent automatically during the initialization, and it is these packets
>> that are shown in the partial log result I showed you in my previous
>> post. (These packets will not match the ipv4_forward table, so the
>> test_bool should not be changed)
>>
>> Thanks
>>
>> Kuo-Feng Hsu
>>
>> /* -*- P4_16 -*- */
>> #include <core.p4>
>> #include <v1model.p4>
>>
>> const bit<16> TYPE_IPV4 = 0x800;
>>
>> /*********************************************************************
>> ****
>> *********************** 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 ipv4_t {
>>      bit<4>    version;
>>      bit<4>    ihl;
>>      bit<8>    diffserv;
>>      bit<16>   totalLen;
>>      bit<16>   identification;
>>      bit<3>    flags;
>>      bit<13>   fragOffset;
>>      bit<8>    ttl;
>>      bit<8>    protocol;
>>      bit<16>   hdrChecksum;
>>      ip4Addr_t srcAddr;
>>      ip4Addr_t dstAddr;
>> }
>>
>> struct metadata {
>>      bool test_bool;
>> }
>>
>> struct headers {
>>      ethernet_t   ethernet;
>>      ipv4_t       ipv4;
>> }
>>
>> /*********************************************************************
>> ****
>> *********************** P A R S E R
>> ***********************************
>> **********************************************************************
>> ***/
>>
>> parser ParserImpl(packet_in packet,
>>                    out headers hdr,
>>                    inout metadata meta,
>>                    inout standard_metadata_t standard_metadata) {
>>
>>
>>      state start {
>> 	/* TODO: add transition to parsing ethernet */
>>          packet.extract(hdr.ethernet);
>>          transition select(hdr.ethernet.etherType) {
>>              TYPE_IPV4: parse_ipv4;
>>              default: reject;
>>          }
>>      }
>>
>>      state parse_ethernet {
>> 	/* TODO: add parsing ethernet */
>>      }
>>
>>      state parse_ipv4 {
>> 	/* TODO: add parsing ipv4 */
>>          packet.extract(hdr.ipv4);
>>          transition accept;
>>      }
>>
>> }
>>
>>
>> /*************************************************************************
>> ************   C H E C K S U M    V E R I F I C A T I O N   *************
>> **********************************************************************
>> ***/
>>
>> control verifyChecksum(in headers hdr, inout metadata meta) {
>>      apply {  }
>> }
>>
>>
>> /*************************************************************************
>> **************  I N G R E S S   P R O C E S S I N G   *******************
>> **********************************************************************
>> ***/
>>
>> control ingress(inout headers hdr, inout metadata meta, inout
>> standard_metadata_t standard_metadata) {
>>
>>      /* This action will drop packets */
>>      action drop() {
>>          mark_to_drop();
>>      }
>>
>>      action ipv4_forward(macAddr_t dstAddr, egressSpec_t port) {
>> 	/*
>> 	* TODO: Implement the logic to:
>>          * 1. Set the standard_metadata.egress_spec to the output port.
>>          * 2. Set the ethernet srcAddr to the ethernet dstAddr.
>> 	* 3. Set the ethernet dstAddr to the dstAddr passed as a parameter.
>>          * 4. Decrement the IP TTL.
>> 	* BONUS: Handle the case where TTL is 0.
>> 	*/
>>          standard_metadata.egress_spec = port;
>>          hdr.ethernet.srcAddr = hdr.ethernet.dstAddr;
>>          hdr.ethernet.dstAddr = dstAddr;
>>          hdr.ipv4.ttl = hdr.ipv4.ttl-1;
>>          meta.test_bool = true;
>>      }
>>
>>      table ipv4_lpm {
>>          key = {
>> 	    /* TODO: declare that the table will do a longest-prefix match (lpm)
>> 	    on the IP destination address. */
>>              hdr.ipv4.dstAddr: lpm;
>>          }
>>          actions = {
>> 	    /* TODO: declare the possible actions: ipv4_forward or drop. */
>>              NoAction;
>>              ipv4_forward;  drop;
>>          }
>>          size = 1024;
>>          default_action = NoAction();
>>      }
>>
>>      apply {
>> 	/* TODO: replace drop with logic to:
>> 	* 1. Check if the ipv4 header is valid.
>> 	* 2. apply the table ipv4_lpm.
>> 	*/
>>          meta.test_bool = false;
>>
>>          if (hdr.ipv4.isValid())
>>          {
>>              ipv4_lpm.apply();
>>          }
>>
>>          if (!meta.test_bool)
>>          {
>>              drop();
>>          }
>>      }
>> }
>>
>> /*************************************************************************
>> ****************  E G R E S S   P R O C E S S I N G   *******************
>> **********************************************************************
>> ***/
>>
>> control egress(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 computeChecksum(
>>      inout headers  hdr,
>>      inout metadata meta)
>> {
>>      /*
>>      * Ignore checksum for now. The reference solution contains a checksum
>>      * implementation.
>>      */
>>      apply {  }
>> }
>>
>>
>> /*************************************************************************
>> ***********************  D E P A R S E R
>> *******************************
>> **********************************************************************
>> ***/
>>
>> control DeparserImpl(packet_out packet, in headers hdr) {
>>      apply {
>>          packet.emit(hdr.ethernet);
>>          packet.emit(hdr.ipv4);
>>      }
>> }
>>
>> /*************************************************************************
>> ***********************  S W I T C H
>> *******************************
>> **********************************************************************
>> ***/
>>
>> V1Switch(
>> ParserImpl(),
>> verifyChecksum(),
>> ingress(),
>> egress(),
>> computeChecksum(),
>> DeparserImpl()
>> ) main;
>>
>>
>>
>>
>>
>> 引述 Andy Fingerhut <andy.fingerhut at gmail.com>:
>>
>>> If you have one or more input packets you can record in one or more
>>> pcap files (perhaps more than one pcap file, if the test case
>>> requires sending packets from multiple different ingress ports), that
>>> sounds like a good test case for someone to try reproducing this issue.
>>>
>>> Andy
>>>
>>> On Wed, Sep 27, 2017 at 12:21 PM, Kuo-Feng Hsu <kh42 at rice.edu> wrote:
>>>
>>>>
>>>> Hi all,
>>>>
>>>> I got a problem about the boolean variable in metadata.
>>>>
>>>> I create a boolean variable in metadata to record whether or not an
>>>> action was called.
>>>> (I knew the usage of table.apply().hit. I also used a one-bit
>>>> variable to work around this problem. Just want to know why the
>>>> following problem
>>>> happened.)
>>>> However, based on the log bmv2 gave me, the boolean variable
>>>> sometimes changes itself without any code explicitly changing it.
>>>> The following is some part of the code and log. Please note the
>>>> test_bool should only change when action ipv4_forward is called, but
>>>> the log doesn't agree.
>>>>
>>>>
>>>>
>>>>
>>>>
>>>> The p4 code:
>>>>
>>>> struct metadata {
>>>>      bool test_bool;
>>>> }
>>>> control ingress(inout headers hdr, inout metadata meta, inout
>>>> standard_metadata_t standard_metadata) {
>>>>      action ipv4_forward(macAddr_t dstAddr, egressSpec_t port) {
>>>>          standard_metadata.egress_spec = port;
>>>>          hdr.ethernet.srcAddr = hdr.ethernet.dstAddr;
>>>>          hdr.ethernet.dstAddr = dstAddr;
>>>>          hdr.ipv4.ttl = hdr.ipv4.ttl-1;
>>>>          meta.test_bool = true;
>>>>      }
>>>>      table ipv4_lpm {
>>>>          key = {
>>>>              hdr.ipv4.dstAddr: lpm;
>>>>          }
>>>>          actions = {
>>>>              NoAction;
>>>>              ipv4_forward;  drop;
>>>>          }
>>>>          size = 1024;
>>>>          default_action = NoAction();
>>>>      }
>>>>      apply {
>>>>          /* TODO: replace drop with logic to:
>>>>          * 1. Check if the ipv4 header is valid.
>>>>          * 2. apply the table ipv4_lpm.
>>>>          */
>>>>          meta.test_bool = false;
>>>>
>>>>          if (hdr.ipv4.isValid())
>>>>          {
>>>>              ipv4_lpm.apply();
>>>>          }
>>>>
>>>>          if (!meta.test_bool)
>>>>          {
>>>>              drop();
>>>>          }
>>>>      }
>>>> }
>>>>
>>>>
>>>>
>>>>
>>>>
>>>> The log:
>>>>
>>>> [16:07:38.437] [bmv2] [T] [thread 30304] [0.0] [cxt 0]
>>>> ipv4_forward.p4(133) Primitive meta.test_bool = false [16:07:38.437]
>>>> [bmv2] [T] [thread 30304] [0.0] [cxt 0]
>>>> ipv4_forward.p4(135) Condition "hdr.ipv4.isValid()" is false
>>>> [16:07:38.437] [bmv2] [T] [thread 30304] [0.0] [cxt 0]
>>>> ipv4_forward.p4(140) Condition "!meta.test_bool" is true
>>>>
>>>> [16:07:38.464] [bmv2] [T] [thread 30304] [1.0] [cxt 0]
>>>> ipv4_forward.p4(133) Primitive meta.test_bool = false [16:07:38.464]
>>>> [bmv2] [T] [thread 30304] [1.0] [cxt 0]
>>>> ipv4_forward.p4(135) Condition "hdr.ipv4.isValid()" is false
>>>> [16:07:38.464] [bmv2] [T] [thread 30304] [1.0] [cxt 0]
>>>> ipv4_forward.p4(140) Condition "!meta.test_bool" is false
>>>>
>>>> [16:07:38.468] [bmv2] [T] [thread 30304] [2.0] [cxt 0]
>>>> ipv4_forward.p4(133) Primitive meta.test_bool = false [16:07:38.468]
>>>> [bmv2] [T] [thread 30304] [2.0] [cxt 0]
>>>> ipv4_forward.p4(135) Condition "hdr.ipv4.isValid()" is false
>>>> [16:07:38.468] [bmv2] [T] [thread 30304] [2.0] [cxt 0]
>>>> ipv4_forward.p4(140) Condition "!meta.test_bool" is true
>>>>
>>>> [16:07:38.660] [bmv2] [T] [thread 30304] [3.0] [cxt 0]
>>>> ipv4_forward.p4(133) Primitive meta.test_bool = false [16:07:38.660]
>>>> [bmv2] [T] [thread 30304] [3.0] [cxt 0]
>>>> ipv4_forward.p4(135) Condition "hdr.ipv4.isValid()" is false
>>>> [16:07:38.660] [bmv2] [T] [thread 30304] [3.0] [cxt 0]
>>>> ipv4_forward.p4(140) Condition "!meta.test_bool" is false
>>>>
>>>>
>>>>
>>>> Thanks.
>>>>
>>>> Sincerely,
>>>> Kuo-Feng Hsu
>>>>
>>>>
>>>>
>>>> _______________________________________________
>>>> P4-dev mailing list
>>>> P4-dev at lists.p4.org
>>>> https://urldefense.proofpoint.com/v2/url?u=http-3A__lists.p4.org_mai
>>>> l
>>>> man_listinfo_p4-2Ddev-5Flists.p4.org&d=DwIGaQ&c=uilaK90D4TOVoH58JNXR
>>>> g
>>>> Q&r=tGW6TKXajnoXSyy1S1P4DHGPe8sj54GGvw-b21n7aWg&m=TlFd3jODvYr5XzMPVx
>>>> V
>>>> OXJ29DPB3wD1yDodBR5kdF7o&s=FvO1Op65nvRmLjeUUWWzTo4MVVU7pGdv-WInvd1bX
>>>> O
>>>> s&e=
>>>>
>>
>>
>>
>>
>> _______________________________________________
>> P4-dev mailing list
>> P4-dev at lists.p4.org
>> https://urldefense.proofpoint.com/v2/url?u=http-3A__lists.p4.org_mailm
>> an_listinfo_p4-2Ddev-5Flists.p4.org&d=DwIGaQ&c=uilaK90D4TOVoH58JNXRgQ&r=tGW6TKXajnoXSyy1S1P4DHGPe8sj54GGvw-b21n7aWg&m=TlFd3jODvYr5XzMPVxVOXJ29DPB3wD1yDodBR5kdF7o&s=FvO1Op65nvRmLjeUUWWzTo4MVVU7pGdv-WInvd1bXOs&e=







More information about the P4-dev mailing list