Repository navigation
ipv6: a tunnel exit point survives a hook that drops the inner datagram - #1252
Open
adamgeorge309 wants to merge 1 commit into
Open
adamgeorge309 wants to merge 1 commit into
adamgeorge309 wants to merge 1 commit into
Conversation
A tunnel exit point passes the decapsulated inner datagram through the netfilter PREROUTING hooks again, in the tunnel branch of Ipv6::localDeliverFinish(). When a hook returned DROP, that branch deleted the datagram, which Ipv6::datagramPreRoutingHook() had already deleted before returning. INetfilter::IHook::DROP means "will be deleted", and the dispatcher datagramPreRoutingHook() does the deleting. Its other caller, Ipv6::handleMessageWhenUp(), continues only on ACCEPT and deletes nothing; the tunnel branch does the same now. The defect came with 95ecc59, which moved IPv6-in-IPv6 decapsulation into Ipv6. INET's own Mobile IPv6 (MIPv6) returns DROP there: on a home agent, Mipv6::datagramPreRoutingHook() drops a decapsulated datagram whose tunnel source is not a known tunnel exit point, INET's form of the check in RFC 6275 Section 10.4.5. tests/module/IPv6_tunnel_exit_drop.test reproduces it with shipped modules only: host A tunnels its traffic to a HomeAgent6 that has no binding for A. Before this commit the run ends with a segmentation fault at t=0.654227418s, on the first decapsulated datagram (the Neighbour Solicitation of the tunnel interface's own Duplicate Address Detection); after it the home agent drops all four decapsulated datagrams and the run reaches its time limit. Change: src.networklayer.ipv6 | behavior.change.fix | test whatsnew
This was referenced Sep 30, 2026
This was referenced Oct 7, 2026
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.
A tunnel exit point crashed when a netfilter PREROUTING hook dropped a decapsulated IPv6-in-IPv6 datagram. INET's own Mobile IPv6 (MIPv6) home agent drops every datagram tunneled to it from a source it has no binding for, so shipped modules reach the crash.
Closes #1251
The problem
The tunnel branch of
Ipv6::localDeliverFinish()(src/inet/networklayer/ipv6/Ipv6.cc:852-856on master) passes the decapsulated datagram through the PREROUTING hooks again:The DROP case of
Ipv6::datagramPreRoutingHook()has already deleted the datagram before it returns, asINetfilter::IHook::DROPdocuments ("will be deleted"). The branch deleted it a second time. The other caller,Ipv6::handleMessageWhenUp()(Ipv6.cc:256), continues only on ACCEPT and deletes nothing; the tunnel branch now does the same. The defect came with 95ecc59, which moved decapsulation fromIpv6TunnelingintoIpv6.On a home agent,
Mipv6::datagramPreRoutingHook()returns DROP for a decapsulated datagram whose tunnel source is not a known tunnel exit point. That is a looser form of the check in RFC 6275 Section 10.4.5, which requires the primary care-of address: "the home agent MUST verify that the Source Address in the tunnel IP header is the mobile node's primary care-of address".Architectural surface
None changed. The fix follows the existing ownership contract of
INetfilter::IHook::DROP.Verification
tests/module/IPv6_tunnel_exit_drop.test, with shipped modules only: host A tunnels its traffic for H to aHomeAgent6that has no binding for A. Release build, master 49e1fa0 with only the new test file added:cd tests/module && inet_run_module_tests -m release --no-build -l ERROR -f IPv6_tunnel_exit_dropreports FAIL. The runner's output is buffered and stops before the crash. Run the test program directly intests/module/work/IPv6_tunnel_exit_drop, which the runner created:stdbuf -o0 -e0 ./IPv6_tunnel_exit_drop -u Cmdenv -f omnetpp.ini -n .:../../../../src, exit status 139. The last lines:The first decapsulated datagram is the Neighbour Solicitation of the tunnel interface's own Duplicate Address Detection. After the commit the home agent drops all four decapsulated datagrams (that Neighbour Solicitation, a Router Solicitation and two User Datagram Protocol (UDP) datagrams: four
Dropping packet: tunnel source is not a known tunnel exit point.lines in the test'stest.out), H receives 0 packets, and the run reaches its 5 s time limit.Commands, release build (
make MODE=release), run on master 49e1fa0 and on this branch before its rebase onto 4eb3bb4 (the 83 commits between them change no file undersrc/):tcp_*,ConvolutionalCoder12/34,EtherHost_lifecycle,ExternalProcess_3,Ieee80211BitDomain/SymbolDomain,Ieee8021d-Rstp/Stp,IPv6_packet_too_big,MIPv6_tcp_handover,PacketGate_1,UDPSocket_1). The new test passes; 347 tests, 301 pass.tests/protocol/ipv6): 26 of 27 pass on both;Rfc8200OverlappingFragmentsfails on master too.inet_run_module_tests -m release --no-build -l ERROR -f 'IPv6_tunnel|NetfilterHooks_Ipv6|IPsec_Ipv6|MIPv6_': 15 tests, 14 pass;MIPv6_tcp_handoverfails on unmodified master too (one of the 46).make MODE=debug):inet_run_module_tests -m debug --no-build -l ERROR -f 'IPv6_tunnel': both pass.doc/project/enforcement/check-architecture.sh src/inet/networklayer/ipv6: PASS.Landing order
This touches the same tunnel branch of
localDeliverFinish()as #1247 (it inserts lines just above the ones changed here).git merge-treemergesIpv6.cccleanly in either order; the only conflict isWHATSNEW, where both add backward compatible item 6. #1236 merges without conflict. Either order works; the pull request that lands second renumbers itsWHATSNEWitem.