[P4-dev] Bool variable in metadata changes itself

Mihai Budiu mbudiu at vmware.com
Mon Oct 2 12:04:14 EDT 2017


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