[P4-dev] TCP/UDP packet modification and further calculations

Andy Fingerhut andy.fingerhut at gmail.com
Thu Sep 27 12:54:31 EDT 2018

A general technique for updating checksums that were calculated over a
variable-length part of a packet, if you are only changing a limited set of
bytes, is to start with the checksum received in the packet, "subtract out"
the effect on the checksum of the original byte contents before you changed
them, and then add in the effect of the new values you changed them to.

The p4-spec Github repository contains a couple of example programs I wrote
for the PSA architecture that demonstrate this:


They use PSA's InternetChecksum extern, so may not be usable for you in the
syntax as demonstrated there, but you may be able to figure out how to
adapt it for your case.  Note that "subtracting" for the Internet 16-bit
checksum is the same as doing a bitwise-complement of a 16-bit word, then
adding that using the Internet checksum's 1's-complement addition (in case
that math fact helps you use some existing facility you have that can add
some bytes using 1's complement addition, but not subtract, you can negate
and use the addition capability).


On Thu, Sep 27, 2018 at 6:40 AM cs.lev <cs.lev at gmx.com> wrote:

> Hi all,
> I am playing with a P4 switch that in some sense manipulates/tries to
> manipulate the UDP/TCP packets that are forwarded from one port to
> another.
> For an easier use case, I use two machines (i.e., VMs) connected to a
> P4 switch (i.e.,bmv2 softswitch).
> The two machines use simple netcat with TCP and UDP for communications
> and I want to achieve that basic communications, i.e., one string typed
> into the netcat at one machine appears at the other machine.
> Again, for brevity (see later) I assume only 4-character-long strings.
> So, when you type 'asdf' into the netcat at a machine, the same 'asdf'
> will appear as should at the other, however when you type 'cats', on
> the receiver site the word 'dogs' will appear.
> In my P4 code, as the string could only be 4-byte long (due to the 4-
> character-length) + a termination 1-byte character (0x0a), I can
> prepare my code that after the UDP header I also want to parse the next
> 5-bytes from the payload/data.
> header definition:
> ```
> header udp_t
> {
>     bit<16> srcPort;
>     bit<16> dstPort;
>     bit<16> len;
>     bit<16> checksum;
>     //payload - we only consider 5 bytes of data
>     bit<40> payload;
> }
> ```
> I have an exact match table on this UDP payload, where I am matchin
> onthe 'cats' (0x63617473) + '0x0a' value
> If table hit happens I replace the 'cats' value to 'dogs'(0x646f6773) +
> '0x0a' value.
> For this change, however, I need to recalculate the UDP checksum,
> otherwise netcat receive side will drop the packet.
> In order to reach this end, I use my eased property that UDP packets
> are of the same length (due to my restriction of 4-character long
> messages) and added the following snippet to the typical
> MyComputeChecksum function after the IP checksum update function call:
> //UDP header checksum
>         update_checksum(
>             hdr.ipv4.protocol == IP_PROTO_UDP,
>             {
>                 hdr.ipv4.srcAddr,
>                 hdr.ipv4.dstAddr,
>                 8w0,
>                 hdr.ipv4.protocol,
>                 hdr.udp.len,
>                 hdr.udp.srcPort,
>                 hdr.udp.dstPort,
>                 hdr.udp.len,
>                 hdr.udp.payload
>             },
>             hdr.udp.checksum,
>             HashAlgorithm.csum16);
> Note that this is working quite well as the payload and length are of
> the same size always.
> LSS; Can someone show me how can I make this dynamic, i.e., when the
> payload (and its length of course) is not known in advance, so it can
> be longer, but the first 4-byte also contains the word 'cats' which
> should be corrected as well?
> In other words, sending the following message works with my solution:
> 'cats'
> but, the following does not:
> 'cats eat fish'
> as my checksum calculation will fail.
> Also, is it possible to do the same thing (even my first eased example)
> for TCP, i.e., how can I compute the TCP checksum for a packet?
> Thank you for considering my request!
> Kind wishes,
> cs.lev
> _______________________________________________
> P4-dev mailing list
> P4-dev at lists.p4.org
> http://lists.p4.org/mailman/listinfo/p4-dev_lists.p4.org
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.p4.org/pipermail/p4-dev_lists.p4.org/attachments/20180927/4b1040bd/attachment.html>

More information about the P4-dev mailing list