[P4-dev] Parse/process dynamic payload

cs.lev cs.lev at gmx.com
Tue Oct 9 03:49:48 EDT 2018


Thank you so much Andy, I will follow this path.
Re. the Options field, yes I have hard-coded that as I was playing with
netcat, which always had the options field with 96 bits width.

Best wishes,
lev


On Mon, 2018-10-08 at 08:47 -0700, Andy Fingerhut wrote:
> In a P4 parser, whenever you call extract() on a fixed length header
> with N bytes, it checks whether there are N bytes remaining in the
> packet, or more.  If there are, the extract succeeds, and the header
> .isValid() becomes true.  If there are not, the parser records a
> PacketTooShort error, and .isValid() for that header remains false.
> 
> In simple_switch, all fields of such a header on which extract failed
> will be 0.  FYI, on other P4 targets, the contents of those header
> fields could be undefined garbage rather than predictable 0 values
> like you get from simple_switch.
> 
> You could modify your parser in these ways to get results probably
> closer to what you were hoping for:
> 
> + change your definition of the TCP header to remove the 2 bytes at
> the end that are part of the payload, which as you mention some
> packets may not have
> + create a new header with those payload bytes, e.g. payload_t
> + Change your parse state for parsing the TCP header so that after it
> extracts the TCP header, it calculates the length of the TCP payload
> in bytes, e.g. meta.tcp_payload_len = (hdr.ipv4.totalLen - IPV4_LEN -
> ((bit<16>) hdr.tcp.dataOffset << 4));
> 
> Then do a transition select statement on the value of
> meta.tcp_payload_len.  The select expression should have cases of 0
> or 1 that transition to accept, and a default case that transitions
> to a new parse state that extracts the new payload header.  With the
> suggested logic above, it will only transition to that parse state if
> there are at least 2 bytes of TCP payload data in the packet.  If
> there are not, that new header you defined for the 2 bytes of payload
> should have .isValid() false when parsing is complete.
> 
> I don't know how important it is to you to get this correct, but your
> TCP header has a fixed length 96-bit field for TCP options.  If you
> want the new payload field to never include TCP option data, you
> should change the definition of that options field to be `varbit`
> instead of `bit`, and do a variable length extract() call in your TCP
> parsing state to calculate the length of the options.
> 
> Andy
> 
> On Mon, Oct 8, 2018 at 5:21 AM cs.lev <cs.lev at gmx.com> wrote:
> > Hi all,
> > 
> > I am (still) playing with P4's capability to modify/monitor the
> > payload
> > in a packet. According to some sources I have found here and on the
> > github, I quickly created a simple P4 application that prints out
> > the
> > processed packet's data, i.e., header information from layer 2 to
> > layer
> > 4.
> > Source code is here:
> > https://github.com/cslev/p4debug
> > 
> > Logging is based on debug tables and exact matches on the different
> > fields of the header.
> > (debug tables can be enabled by `#define` conditions in the
> > beginning
> > of the source code - now IP/TCP is enabled for ingress processing.
> > 
> > 
> > I have encountered that if I further define a couple of bytes to
> > parse
> > in the header, i.e., when I read the payload, for instance, 2 bytes
> > after the TCP options field, I became able to match on those
> > specific
> > bytes as well.
> > However, if the payload is shorter than 2-bytes, the whole packet
> > and
> > its headers are treated as a corrupted packet and monitoring (or
> > even a
> > TCP header based routing) is not working.
> > 
> > In particular, assume I have a TCP netcat connection between two
> > hosts,
> > and the client sends two characters, say, two 'a' (which is 2 bytes
> > + 1
> > byte EOL character) then parsing is working well and I can see the
> > following in the console:
> > * standard_metadata.ingress_port: 0000
> > * meta.tcp_metadata.tcp_len     : 0029
> > * hdr.tcp.srcPort               : da2e
> > * hdr.tcp.dstPort               : 115c
> > * hdr.tcp.seqNo                 : 76dc4b4b
> > * hdr.tcp.ackNo                 : 8dcbb939
> > * hdr.tcp.dataOffset            : 08
> > * hdr.tcp.flags_1               : 00
> > * hdr.tcp.flags_2               : 01
> > * hdr.tcp.flags_3               : 08
> > * hdr.tcp.window                : 00e5
> > * hdr.tcp.checksum              : 5ffa
> > * hdr.tcp.urgentPtr             : 0000
> > * hdr.tcp.payload               : 6161
> > 
> > However, if I only send an empty character with the 1-byte EOL
> > character (0x0a) summing up only 1-byte payload, then not just the
> > payload parsing "crashes in some sense" but I get the following
> > output:
> > * standard_metadata.ingress_port: 0000
> > * meta.tcp_metadata.tcp_len     : 0000
> > * hdr.tcp.srcPort               : 0000
> > * hdr.tcp.dstPort               : 0000
> > * hdr.tcp.seqNo                 : 00000000
> > * hdr.tcp.ackNo                 : 00000000
> > * hdr.tcp.dataOffset            : 00
> > * hdr.tcp.flags_1               : 00
> > * hdr.tcp.flags_2               : 00
> > * hdr.tcp.flags_3               : 00
> > * hdr.tcp.window                : 0000
> > * hdr.tcp.checksum              : 0000
> > * hdr.tcp.urgentPtr             : 0000
> > * hdr.tcp.payload               : 0000
> > 
> > Of course, this always happens for the ACK messages back from the
> > server as there is no payload at all.
> > 
> > Furthermore, hdr.tcp.isValid() function also fails - I guess
> > because it
> > validates the header according to my specification, which should
> > contain the 2-byte big payload as well.
> > I can overcome this by having a condition on the ipv4.protocol
> > field
> > instead if I want to catch TCP packets, but still the TCP header
> > information in the debug tables show zeros.
> > 
> > Is there any way to overcome this?
> > Maybe putting payload related part into metadata and parse that
> > part
> > with lookahead() functions? Would it even work with dynamic payload
> > length?
> > 
> > Thanks,
> > cs.lev
> > _______________________________________________
> > P4-dev mailing list
> > P4-dev at lists.p4.org
> > http://lists.p4.org/mailman/listinfo/p4-dev_lists.p4.org
> > 



More information about the P4-dev mailing list