-
Notifications
You must be signed in to change notification settings - Fork 87
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
fix Ipv6 code #428
fix Ipv6 code #428
Conversation
CI reports tests are failing. Locally I get exceptions in the |
I've enabled ocaml-ci too, and that sees lots of failures on this PR (but master seems mostly OK, except for some 32-bit problems in the tests). It's a shame Alcotest doesn't provide better output in this case (looks like it just exits without a message). |
@talex5 thanks for enabling OCaml-CI. I don't understand the failure(s) -- neither do I understand what the purpose of e.g. the connect tests is (and their connection to the changes in this PR, which are only IPv6 related). |
@hannesm I added those tests a long time ago - I can take a look to see if I can reproduce the errors. The connect test is one of the first tests we had and it only verifies that the stack can connect and talk to itself (I think it also records the pcap data so it could be extended to verify that the handshake is correct). The iperf test was intended to be a tool to test for throughput regressions, but it has limited use in travis CI where performance will vary anyway -- iirc it has caught some bugs related to longer transfers hanging. |
Running the tests with
This is a bit strange, as the stack used by To check if it could be related to the
Could the |
thanks @MagnusS for explaining and investigating.
that is my intuition as well.
I don't know, but why should this PR modify the behaviour / lead to exceptions? |
The ipv6 test disconnected from the vnetif backend while the stack was still running, resulting in a `Not_found` exception being returned from mirage-vnetif when Ethernet.write was called. This only became a problem in a recent commit that fixed an issue that prevented some of the background timers from running in the IPv6 stack. The V.disconnect call seems to have been added to work around another IPv6 issue where the UDP sender will queue packets with an empty source address until an IPv6 address is configured. This results in multiple packets with empty source address being received after the first correct packet, unless the receiver disconnected from the backend before this happens. This updates the test to not send UDP packets until an IP address is acquired and removes the call V.disconnect in the receiver. It does not change the queuing behaviour of the IPv6 stack, which may also be incorrect.
@hannesm I pushed an update to your branch to fix the ipv6 test as discussed on slack. To summarise the problem: The error seems to be caused by an unchecked mac address lookup that happens if you try to write ethernet frames after disconnecting the netif provided by It looks like the During testing I also added a counter to the payload and this is what the receiver sees if the sender starts sending without an IP. The queue is released by the sender stack when an IP is available:
So there still seems to be some potential problems here (ordering is wrong, src IP empty)- but this at least makes the test pass after an IP has been acquired. (I also added mirage/mirage-vnetif#32 to track the unhelpful exception in mirage-vnetif) The MTU restricted iperf test is still failing, I'll try to take a look at that tomorrow. |
The MTU-limited iperf test was only succeeding if executed after the mtu+tcp test, as the mtu+tcp test would set the MTU to 9000. The iperf test would fail if executed directly as the expected Ethernet frame size was set equal to the MTU, leaving no room for the Ethernet header. I've added a commit to fix both issues (more details in the commit message) |
The previous backend contained a ref to the MTU in the module, so the MTU was remembered between tests. The iperf test would not succeed unless the mtu+tcp test had run previously, as it set the MTU to 9000 instead of the expected 1500. This renames the MTU enforced backend to Frame_size_enforced to make it clear that the size limit is on the Ethernet layer. The frame size is stored in the returned `t` and is now reset between tests. A helper function is also added to set the enforced frame size based on the IP layer MTU (MTU + size of ethernet header). This also re-enables the iperf test as it now succeeds. The previous failure was due to the enforced frame size being equal to the MTU, leaving no room for the Ethernet header.
Your changes LGTM @hannesm - with the test updates CI is also green again |
Co-authored-by: Hannes Mehnert <[email protected]>
CHANGES: * Assorted IPv6 improvements (mirage/mirage-tcpip#428 mirage/mirage-tcpip#431 mirage/mirage-tcpip#432 @MagnusS @hannesm) - set length in packets to be sent - preserve updated ctx from Ndv6.handle - fix ICMP checksum computation - implement Mirage_stack.V6 signature - add connect, mtu, iperf tests - fix DAD protocol implementation (and test it) - avoid out of bounds accesses of IPv6 packets (check length before accessing) * Fix 32 bit issues (@MagnusS) * Implement stack-direct and tcp disconnect: tear down existing connections (mirage/mirage-tcpip#429 @hannesm) * Treat broadcast address of network as broadcast as well (mirage/mirage-tcpip#430 @hannesm, reported in mirage/mirage-tcpip#427)
I was curious what the current state of MirageOS and IPv6 is (a question coming up every now and then). Thus I tried with link-local addresses the mirage-skeleton example device-usage/ping6, and discovered:
with these changes, the ping6 example boots and replies to icmpv6 echo requests. This is great progress IMHO (but there's likely some more stuff to fix/enhance before MirageOS is IPv6 ready).
Any reviews are appreciated.