I have two questions about digest
and standard_metadata.instance_type
in bmv2:
- 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.
- 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!).
- Please attach your P4 so it is a little easier for anyone around to help you
- 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:
-
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.
-
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.