Repository navigation
ipv6: fix: keep a datagram with a link-local source on its link - #1358
Open
adamgeorge309 wants to merge 1 commit into
Open
adamgeorge309 wants to merge 1 commit into
adamgeorge309 wants to merge 1 commit into
Conversation
Ipv6::routePacket() refused to forward a datagram whose destination address is link-local, but did not look at the source address, so a router forwarded a unicast datagram with a link-local source onto another link. Request for Comments (RFC) 4291 Section 2.5.6 says that routers must not forward packets with link-local source or destination addresses to other links, and RFC 4007 Section 9 discards a packet that would leave the zone of its source address and, for a unicast destination, answers with an Internet Control Message Protocol for Internet Protocol version 6 (ICMPv6) Destination Unreachable, code 2, "beyond scope of source address" (RFC 4443 Section 3.1). After choosing the output interface, routePacket() now drops a forwarded datagram whose source is link-local if the output interface differs from the arrival interface (INET has no zone model, so the interface stands for the link; a datagram sent back through it stays in the zone of its source). The drop emits packetDropped with OTHER_PACKET_DROP and sends Destination Unreachable, code 2, unless the datagram is a Redirect (RFC 4443 Section 2.4 (e.2)). Icmpv6DestUnav gains BEYOND_SCOPE_OF_SOURCE = 2, where a comment stood. tests/module/IPv6_forwarding_link_local_source.test pings an off-link host from a link-local address through a router and checks that the router forwards none of the 3 Echo Requests and that the sender receives 3 Destination Unreachable messages with code 2; before this commit, the router forwarded all 3. This commit records the changed tplx, ~tNl and ~tND fingerprints of three examples.csv rows: examples/ipv6/mipv6 Handover and RouteOptimizationTwoCNs, examples/ipv6/mipv6roaming Roaming. In Handover and Roaming, a correspondent node pings from its link-local address before it has a global address; in all three, the home agent used to tunnel its own Redirects, returned by a router, to the mobile node. Their tyf fingerprints and the mipv6-refactoring.csv rows, which fail on master, are kept. The statistical baselines of the three configurations change. Change: src.networklayer.ipv6.Ipv6 | behavior.change.fix | test fingerprint statistical whatsnew
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
An Internet Protocol version 6 (IPv6) router forwarded a unicast datagram whose source address is link-local onto another link, because
Ipv6::routePacket()checked only the destination address. It now drops such a datagram and answers with an Internet Control Message Protocol for IPv6 (ICMPv6) Destination Unreachable message, code 2, "beyond scope of source address": Request for Comments (RFC) 4291 Section 2.5.6 forbids the forwarding, and RFC 4007 Section 9 requires the error.Risk: simulations in which a node sends from its link-local address to an off-link destination, or in which a router's Redirect with a link-local source crosses another router, change. Three fingerprint rows of
examples.csv(Mobile IPv6 (MIPv6) Handover, RouteOptimizationTwoCNs, Roaming) are re-recorded, and their statistical baselines in the statistics repository need re-recording after merge. Merge after #1256: without it,tests/module/IPv6_tunnel.testfails (see Verification).Closes #1357
One commit:
ipv6: fix: keep a datagram with a link-local source on its link.The problem
src/inet/networklayer/ipv6/Ipv6.cc:479-484on master refuses to forward a datagram with a link-local or loopback destination. Nothing on the forwarding path checks the source address, so a router forwards a datagram with anfe80::/10source to any interface the routing table picks. Code 2 of Destination Unreachable was not defined:Icmpv6DestUnavhad//2 - NOT ASSIGNEDin its place.The change
Ipv6::routePacket(), after the output interface is chosen and before the Redirect and FORWARD hook steps: a forwarded datagram (!fromHL, with an arrival interface) whose source is link-local and whose output interface differs from its arrival interface is dropped. INET has no zone model, so the arrival interface stands for the link. A datagram sent back out of its arrival interface stays on its link, so it does not leave the zone of its source address; that case, which is the Redirect trigger, is unchanged.numDropped, emitspacketDroppedwithOTHER_PACKET_DROP, and callssendIcmpError(..., ICMPv6_DESTINATION_UNREACHABLE, BEYOND_SCOPE_OF_SOURCE). No error is sent for a Redirect (RFC 4443 Section 2.4 (e.2)).Icmpv6::validateDatagramPromptingError()already suppresses errors about ICMPv6 errors, about multicast destinations, and about datagrams that arrived in a link-layer broadcast or multicast frame.Icmpv6Type.msg:BEYOND_SCOPE_OF_SOURCE = 2inIcmpv6DestUnav. The Transmission Control Protocol (TCP) treats it as a soft error:isHardIcmpv6Error()lists only codes 1 and 4.No C++ interface, Network Description (NED) parameter, message field or feature descriptor changes; the enum gains one value.
Not addressed here: the error is routed like every other locally originated datagram to a link-local destination, by longest-prefix match over the
fe80::/10routes that every non-loopback interface adds. On a router where the arrival interface is not the one that match picks, the error leaves through the wrong interface and does not reach the sender. In the reproduction with the two links swapped, the 3 errors left through eth0 while hostA was on eth1. Pinning the error to the arrival interface would make it a datagram with an output interface but no next-hop determination, which is the separate defect of #1151 (pull request #1152).Also not addressed: a datagram decapsulated at a tunnel exit keeps the physical interface the tunnel packet arrived on as its arrival interface. An inner datagram with a link-local source that leaves through that same interface is therefore still forwarded; one that leaves through another interface, as in
IPv6_tunnel.test, is dropped. Multicast forwarding (routeMulticastPacket()) is unchanged. A datagram that goes out of another interface attached to the same link does not leave the zone either; without a zone model, it is now dropped.Verification
Release build (
make MODE=releasein the root andtests/module/lib), each suite run on masterbba1db4c81and with this change.New module test
tests/module/IPv6_forwarding_link_local_source.test:hostA --- router --- hostB, hostA pings hostB's global address fromfe80::8aa:ff:fe00:a. It checks that the router never logs a next hop on eth1 for hostB, that it logs the drop 3 times, and that hostA dispatches 3Icmpv6DestUnreachableMsgwith code 2. It fails on master (run before the master baseline), where the router forwards all 3 Echo Requests to hostB and hostB's replies tofe80::8aa:ff:fe00:aare dropped by the router as link-local destinations, and passes with this change.tests/fingerprint: ./fingerprinttest -s -F tyftests/module: inet_run_module_tests -m release --no-build -l ERRORIPv6_tunnelfails (below); the other failures are the same tests by nametests/module: ... -f 'IPv6_tunnel|IPv6_forwarding_link_local_source'with #1256's commitad02cc70aeapplied on topOf the 289 module failures on master, 274 are
tcp_*tests and 15 areConvolutionalCoder12,ConvolutionalCoder34,DimensionalMediumAnalogModel_PrintAttenuation_1,EtherHost_lifecycle,ExternalProcess_3,Ieee80211BitDomain,Ieee80211BlockAckVariant_1,Ieee80211SymbolDomain,Ieee8021d-Rstp,Ieee8021d-Stp,IPv6_packet_too_big,LogNormalShadowing_Correlated_4,MIPv6_tcp_handover,PacketGate_1,UDPSocket_1. The 5 fingerprint failures on master are rows ofmipv6-refactoring.csvwhose recorded~tNlbfingerprints are stale; the 62 errors are configurations whose optional features are not built.IPv6_tunnel.test: host A sends into a tunnel interface whose exit is router B. On master the inner datagrams carry the link-local sourcefe80::(#1255), and B forwarded them to H. With this change B drops them, all 8, and the test's "received 8 packets" check fails. #1256 gives those datagrams a global source.Fingerprint rows: in
examples.csv,examples/ipv6/mipv6Handover and RouteOptimizationTwoCNs andexamples/ipv6/mipv6roamingRoaming change theirtplx,~tNland~tNDfingerprints, which this commit records. Theirtyffingerprints (./fingerprinttest -s -f tyf -m mipv6 examples.csv, run on master and with this change) differ from the recorded values on master too, and so does the pmipv6 row'styf. These, and the 3 changed~tNlbrows ofmipv6-refactoring.csv, are left as they are. What changes in those runs, with this change:fe80::8aa:ff:fe00:ccompletes at 2.43 s and the global address is assigned, tentative, at 3.31 s and usable at 5.24 s). R_2 in Handover and the backbone router in Roaming drop them.The correspondent node's ping results (
pingRxSeq:count,numLost:last) are the same in RouteOptimizationTwoCNs. In Handover, 112 replies arrive instead of 108 (sequence numbers 43, 125, 126 and 127 are added). In Roaming, 111 arrive instead of 112 (84 and 85 at 43.0 s and 43.5 s are lost, 122 at 62.0 s is added). In Roaming, no new drop happens near those times. In Handover, the home agent drops a returned Redirect at every reply in 22.5–39 s and 63.5–69.5 s, including the four added ones. Why only these replies change is not traced.Gates:
check-pull-request.sh --base origin/master(commits, classification, includes, NED parameters, description),check-source-seals.sh --base origin/masterandcheck-architecture.sh src/inet/networklayerpass.Relationship to other pull requests
IPv6_tunnel.test, see above. Both changeIpv6.ccin different functions.WHATSNEW; whichever merges later renumbers.