OpenFastPath / ofp

OpenFastPath project
BSD 3-Clause "New" or "Revised" License
351 stars 126 forks source link

Outgoing TCP RST contains bad TCP header fields #189

Closed jvillanyi closed 6 years ago

jvillanyi commented 6 years ago

Whenever an incoming TCP packet triggers a RST response, the outgoing RST contains incorrect TCP header fields.

In the example below a packet arrives from 192.168.50.101 port 37450 to 192.168.50.2 port 45000 for a non-existent connection. After the syn-cookie validation fails, the OFP TCP stack drops the packet and sends out a RST:

Oct 25 11:47:06.748 tcp_input: 192.168.50.2:45000 <= 192.168.50.101:37450 ACK PUSH (seq:365905376 ack:520376545 win:30016 len:221) Oct 25 11:47:06.753 ofp_tcp_syncache.c:845 Segment failed SYNCOOKIE authentication, segment rejected (probably spoofed) Oct 25 11:47:06.757 tcp_output: 192.168.50.2:0 => 192.168.50.101:6192 FIN ACK RST (seq:257 ack:134873144 win:29167 len:231) ......

However, as the logs above show, the various TCP header fields (source and destination port numbers, flags, etc.) are all wrong in the outgoing RST.

jvillanyi commented 6 years ago

The root cause of the problem is that the function ofp_tcp_input() removes the L2 header from the beginning of the received packet but only updates the l2_offset and l3_offset fields within the ODP packet header, and not the l4_offset.

If ofp_tcp_input later finds any issues with this incoming packet which make it necessary for the packet to be dropped and a RST to be sent back, it will call ofp_tcp_respond (via tcp_dropwithreset) to construct a RST response using the ODP buffer of the incoming packet. The ODP packet header of the newly created RST will inherit the wrong l4_offset and will cause the TCP header fields to be accessed at the wrong offset.

The patch below fixes the problem by setting the correct l4_offset for the incoming packet within ofp_tcp_input().

--- src/ofp_tcp_input.c | 1 + 1 file changed, 1 insertion(+)

diff --git a/src/ofp_tcp_input.c b/src/ofp_tcp_input.c index b129108..74eb839 100644 --- a/src/ofp_tcp_input.c +++ b/src/ofp_tcp_input.c @@ -582,6 +582,7 @@ ofp_tcp_input(odp_packet_t m, int off0) odp_packet_pull_head(m, odp_packet_l3_offset(m)); odp_packet_l2_offset_set(m, 0); odp_packet_l3_offset_set(m, 0); + odp_packet_l4_offset_set(m, off0);

ifdef INET6

    isipv6 = (((struct ofp_ip *)odp_packet_data(m))->ip_v == 6) ? 1 : 0;

---

I have submitted this patch to the OFP mailing list as well.