Digest and recirculate in bmv2

I have two questions about digest and standard_metadata.instance_type in bmv2:

  1. Why I can’t digest standard_metadata.instance_type to controller? I use digest(1, standard_metadata.instance_type) in ingress, but controller did’t receive any message. However, when I digest other things such as digest(1, hdr.ipv4.srcAddr), it’s ok.
  2. when ingress processes a recirculated packet, how can I specify it’s a recirculated packet by using standard_metadata.instance_type or other ways to do so?I don’t know what’s the value should be. I found some information in here and used PKT_INSTANCE_TYPE_RECIRC . But it occurred an error:
    [--Werror=not-found] error: PKT_INSTANCE_TYPE_RECIRC: Not found declaration .

Eder Ollora Zaballa in slack p4#general gave some suggestions (thanks a lot!).

  1. Please attach your P4 so it is a little easier for anyone around to help you :微笑的脸:
  2. That is a strange error that other devs might have seen before. I have seen that PKT_INSTANCE_TYPE_RECIRC equals to 4 from Andy’s p4-guide. You could define a struct that incorporates a 32 bit field (for srcAddr) and another 1 bit field (to signal a recirculated packet). Try to check the value of instance_type == 4 or recirculate_flag != 0 and if so then you know it is a recirculate packet, according to the website I linked. I have not tested this so keep that in mind

By change, I found the main reasons why Q1 happened and thus can solve Q2. It’s about 2 aspects:

  1. As I asked at slack p4#general (link), digest seemingly sends messages as a blocking way in bmv2 using simple_switch_CLI apis, which means if controller miss a digest message from bmv2 switch and don’t ack, the switch will wait for the ack and block subsequent digest messages. So controller should run before switch sends digest message.

  2. I did run controller before switch sends digest messages, but I ignored the real traffic in my experiment environment. I found there are MDNS ICMP6 packet in my env. using wireshark. And I did’t use digest in the statement that judge whether the packet is a ipv4 packet, instead I use it outside, like this:

    apply{
        digest(1, standard_metadata.instance_type);
        if (hdr.ipv4.isValid()){
        ...
        }
    }
    

    To deal with only target packet, it should be:

    apply{
        ...
        if (hdr.ipv4.isValid()){
    	    digest(1, standard_metadata.instance_type);
        ...
        }
    }
    

According to discussions above, put the digest in condition statement will solve the problem.

In the documentation for BMv2 and the v1model architecture here: behavioral-model/simple_switch.md at main · p4lang/behavioral-model · GitHub

there is a bullet point documenting the instance_type field. That documentation contains a link to several lines of P4 code that give suggested names and constant values for all of the possible values of instance_type.

It would be more convenient if those constants were defined in the v1model.p4 #include file, too, but as of now they are not.