Adding ipv4 options header in p4 program


I want to get guidance about adding ipv4 options header a at p4 switch. The details are as follows:

My network has a source , a p4 simple switch, a non p4 hop , a p4 switch and a destination

I want to use option field of the ipv4 (as a separate header) for telemetry at fist p4 switch and want to make it invalid at the second p4 switch.
In my scenario, from source the packets do not have option data, rather I have to add the option header (total 64 bits) at the first p4 switch. In p4 program, I

  1. update the hdr.ipv4.ihl by an additional value of 2 (2 times 32-bits)
  2. update the hdr.ipv4.packetLength by an additional value of 8 (8 bytes)
  3. update udp header length by 8
    update the checksums of ipv4 (including option fields) and udp checksum using following code
    { hdr.ipv4.version,
    hdr.ipv4_option.value, //I am using timestamp value of 68 so next hop (not a p4 switch can transmit the packet onwards)
    hdr.ipv4_option.swid, //switch id (16 bits)
    hdr.ipv4_option.packet_count // (32 bits)
     { hdr.ipv4.srcAddr,
         meta.Len, //this i calculated earlier by hdr.ipv4.packetLen - hdr.ipv4.ihl
     hdr.udp.checksum, HashAlgorithm.csum16);

My packets do not arrive at switch 2, when I use the option field and update the checksum accordingly. Am I doing something wrong? Any help with be highly appreciated.


If you are adding the IPv4 options immediately after the base 20-byte IPv4 header, before the UDP header, then there is no reason to update the UDP header at all, neither its length nor its checksum.

When you say “my packets do not arrive at switch 2”, are you calling the non-P4 switch “switch 2”, or are. you calling the second p4 switch “switch 2”?

In either case, if you can use tcpdump or similar to capture the packet leaving the “p4 simple switch”, and load it into Wireshark, and enable IPv4 and UDP checksum checking in Wireshark (this checking is typically disabled by default when you install Wireshark), that can help you see exactly the contents of the packets as sent by your “p4 simple switch”, and whether its IPv4 checksum and UDP checksums are correct.

In general, if a packet is getting dropped, it is important to determine exactly what step of the way the packet is getting dropped, and what its contents were in the last place you can record before it was dropped, to minimize the possible locations where the packet is getting dropped.

If the IPv4 checksum is incorrect leaving your p4 simple switch, I would strongly suspect that the non p4 hop could be checking it, and dropping the packet because of an incorrect IPv4 header checksum.

Even if it is correct, depending upon how the non p4 hop handles packets with IPv4 options, I would wonder whether it might be discarding packets with unrecognized IPv4 options. I don’t know the typical behavior of IP routers for such packets.

Thank you Andy,
Please see the points below to better understand my issue.

  • In my network, a p4-switch (1) lies on S1u interface of an LTE testbed, and a p4-switch (2) lies on SGi interface.Since I am adding options to the inner ipv4 of a message crossing a GTP tunnel, I have to update length related fields in IPv4 (inner), GTP, UDP (outer) and IPv4 (outer) headers of the message.
    Other than updating IPv4 (inner) and UDP (outer) header checksum, I am also updating IPv4 (outer) checksum field.

  • Switch 2, is also a p4 simple switch that lies at SGi interface, the intermediate hop between switch 1 and 2 is SPGWU

  • I am not sure if I am updating the checksums correctly especially UDP. Can you please comment on it,

  • As you advised, I will use Wireshark to figure out what goes wrong.


Your second message does clarify matters. It makes sense that you need to update the UDP length and checksum (note that if the packet’s UDP checksum was 0 when you received it, you should leave it at 0. The sender did not calculate, so no reason for you to do so, either).

I do not know if the v1model update_checksum_with_payload() call you made will work as you desire or not, as I have not used it before. It is not clear to me why you are passing it both meta.Len and hdr.udp.plength, though. Should those two values always be the same as each other? If yes, you can use hdr.udp.plength in both places, but I guess as long as they are always equal there should be no bug there.

Hi Andy,
Thanks for the help.

I retain UDP checksum to be zero.
The packet transfer works now.

Mah-Rukh Fida