Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Compute TCP checksum #29

Merged
merged 6 commits into from
Mar 14, 2014
Merged

Compute TCP checksum #29

merged 6 commits into from
Mar 14, 2014

Conversation

seliopou
Copy link
Collaborator

@seliopou seliopou commented Mar 6, 2014

Construct the pseudoheader and ones complement that with the serialized packet (and a zero'd out checksum field).

Construct the pseudoheader and ones complement that with the serialized
packet (and a zero'd out checksum field).
@reitblatt
Copy link
Collaborator

Does the switch not compute this checksum for us? IIRC it will for the IP checksum.

@seliopou
Copy link
Collaborator Author

seliopou commented Mar 7, 2014

If the packet's modified on the controller, the switch won't recompute checksums. @mcanini and I ran into this issue while trying to setup an HTTP request bouncer for the demo.

@adferguson
Copy link
Contributor

why is removing the checksum field from the equality test the correct fix? shouldn't it be equal when you round-trip unmarshalling and re-marshalling?

@adferguson
Copy link
Contributor

to follow-up: arbitrary_tcp and arbitrary_udp should set the checksum field properly, now that the marshalling code is capable of doing the same.

also, while the round-trip testing is clearly useful and has caught many bugs, it shows this approach has a weakness in testing checksum code. ideally, there should be some binary blobs with captured packets, which the unmarshall -> remarshall pipeline should now be able to match (huzzah!), including the checksums which were generated by a non-ocaml-openflow implementation.

hope this makes sense.

@mcanini
Copy link

mcanini commented Mar 7, 2014

Odd enough I cannot find mention in the OpenFlow specs that setting the TCP or UDP src/dst port will cause the switch to compute a new checksum. Seems obvious that it should happen though.
In fact CPqD's implementation does exactly that: https://github.com/mcanini/ofsoftswitch13/blob/master/udatapath/dp_actions.c#L178

@@ -883,7 +898,8 @@ module Ip = struct
let bits = Cstruct.shift bits header_len in
match pkt.tp with
| Tcp tcp ->
Tcp.marshal bits tcp
Tcp.marshal bits tcp;
Tcp.checksum bits pkt.src pkt.dst tcp
| Udp udp ->
Udp.marshal bits udp
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The UDP checksum should also be computed

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mcanini UDP checksum requires some more thought with respect to the interface, as the checksum is optional.

Arbitrary instances for TCP and UDP simply set it to zero. Since the
marshal code recompute the checksum, the 0 value will not be preserved
and the roundtrip property will fail.

A simple way to get around this is to marshal and unmarshal a TCP or UDP
packet once, which will set the chksum field to the proper value, and
then check that the roundtrip property holds on that packet.
@mcanini
Copy link

mcanini commented Mar 14, 2014

LGTM

mcanini pushed a commit that referenced this pull request Mar 14, 2014
@mcanini mcanini merged commit 06286c3 into master Mar 14, 2014
@mcanini mcanini deleted the checksum branch March 14, 2014 22:54
@seliopou seliopou mentioned this pull request Mar 16, 2014
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants