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

cs.lev cs.lev at gmx.com
Thu Sep 27 09:39:46 EDT 2018


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




More information about the P4-dev mailing list