Repository navigation
icmpv6: send no address-resolution NS from a tentative address - #1342
Open
adamgeorge309 wants to merge 1 commit into
Open
adamgeorge309 wants to merge 1 commit into
adamgeorge309 wants to merge 1 commit into
Conversation
Address resolution sent its Neighbor Solicitation (NS) from a tentative address: initiateAddressResolution() took the source of the prompting datagram when the interface had it, tentative or not, and otherwise getPreferredAddress(), which prefers a tentative global address to a verified link-local one. Optimistic Duplicate Address Detection (DAD) reaches this path. RFC 4861 Section 7.2.2 takes the source from the assigned addresses, RFC 4862 Section 5.4 does not count a tentative address as assigned, and RFC 4429 Section 3.2 forbids an Optimistic address as the source of an NS. A new file-local function, chooseNsSourceAddress(), takes the datagram's source if it is assigned, as before; otherwise getPreferredAddress() if it is assigned, as before for a source that is not on the interface; otherwise the link-local address or another unicast address of the interface that is not tentative. initiateAddressResolution() uses it, and if there is none, sends nothing and leaves the entry INCOMPLETE with the datagram queued; makeTentativeAddressPermanent() starts address resolution for such entries on the interface when DAD of an address completes. processArTimeout() checks the source before each retransmission (a Mobile IPv6 handover marks addresses tentative again) and chooses another one or waits. tests/module/IPv6_ND_no_solicitation_from_tentative_address.test, a host under Optimistic DAD pinging its router from t=0, checks that no NS from the tentative address comes before DAD completes; before this commit the host sent them at 0, 1 and 2 s. Four fingerprint rows change, and this commit records them: examples/inet/hierarchical99 IPv6 in examples.csv and mipv6-refactoring.csv, and examples/ipv6/mipv6 Handover and examples/ipv6/mipv6roaming Roaming in examples.csv; in each, one node sends before its link-local DAD completes, and the applications deliver the same as before. The statistical baselines of Handover and Roaming change. Change: src.networklayer.icmpv6.Ipv6NeighbourDiscovery | 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.
Address resolution sent its Neighbor Solicitation (NS) from a tentative address, one whose Duplicate Address Detection (DAD) had not completed. RFC 4861 Section 7.2.2 takes the source from the addresses assigned to the interface, RFC 4862 Section 5.4 does not count a tentative address as assigned, and RFC 4429 Section 3.2 forbids an Optimistic address as the source of an NS. The NS now goes out from an address that is not tentative; with none on the interface, address resolution waits until DAD of an address completes.
Risk: IPv6 traffic that needs address resolution while every address of the interface is tentative waits for DAD instead of being resolved at once: under Optimistic DAD, or a node that sends, or a router that forwards, before DAD of its link-local address completes. A datagram whose source is assigned, and a forwarded datagram on an interface whose preferred address is assigned, get the same NS source as on master. Four fingerprint rows change and are recorded here, the applications deliver the same as on master in the 15 configurations checked (the three whose fingerprints change and the twelve listed below), and two statistical baselines need re-recording after the merge. If DAD finds the link-local address duplicate before any other address is assigned, datagrams to unresolved neighbours stay queued (see The fix).
Closes #1341
One commit:
icmpv6: fix: send no address-resolution NS from a tentative address.The problem
initiateAddressResolution()(src/inet/networklayer/icmpv6/Ipv6NeighbourDiscovery.cc:672-681on master) takes the source of the prompting datagram ifhasAddress()finds it on the interface, and otherwisegetPreferredAddress().hasAddress()is true for a tentative address (src/inet/networklayer/ipv6/Ipv6InterfaceData.cc:370-373), andchoosePreferredAddress()prefers a tentative global address to a link-local one. Under Optimistic DAD (optimisticDad = true) every datagram from the Optimistic address to a neighbour not yet in the Neighbour Cache reaches this path; so does a datagram whose sender set a tentative source (#1295).RFC 4429 Section 3.2:
RFC 4862 Section 5.4: "A tentative address is not considered "assigned to an interface" in the traditional sense." The unspecified address is not an alternative: by Section 5.4.3 an NS from it comes from a node performing DAD.
The fix
chooseNsSourceAddress(), takes the datagram's source if it is on the interface and not tentative, as before; otherwisegetPreferredAddress(), as before, if it is not tentative; otherwise the link-local address if it is not tentative; otherwise the first unicast address of the interface that is not tentative.initiateAddressResolution()uses it.No address assigned to the interface yet, address resolution waits for DADand returns: the entry stays INCOMPLETE with noarTimer, andprocessIpv6Datagram()queues the datagram in it as for any INCOMPLETE entry.processArTimeout()checks the stored source before each retransmission: if it is no longer on the interface or has become tentative (Mobile IPv6 handover marks the addresses tentative again), it chooses a new one withchooseNsSourceAddress()from the source of the first queued datagram, and with none it deletes the timer and leaves the entry waiting like a new one.makeTentativeAddressPermanent(), after assigning an address, callsinitiateAddressResolution()for every INCOMPLETE entry of that interface that has queued packets and noarTimer, with the source of the first queued datagram.Every non-loopback interface runs DAD on its link-local address, and
initiateDad()assigns it at once when DAD is disabled, so an entry waits only while DAD runs. If DAD finds the link-local address duplicate before any other address is assigned (DAD of a global address starts only after link-local DAD completes), nothing wakes the entry, and the datagrams for that neighbour stay queued without an Internet Control Message Protocol (ICMP) error, where master gave up after MAX_MULTICAST_SOLICIT NSs and returned Address Unreachable. RFC 4429 Section 3.2 also says that a node MUST NOT perform address resolution for a packet from an Optimistic address, and SHOULD send it to a default router or buffer it until DAD completes. This change buffers such a packet only while the interface has no assigned address; otherwise it resolves from an assigned address, which avoids the Neighbor Cache disruption that Section 2.2 gives as the reason, but departs from that MUST NOT. Forwarding to a default router is not implemented. An INCOMPLETE entry with queued packets and no timer that something other than this path created also gets address resolution then. No C++ interface, Network Description (NED) parameter, message field or feature descriptor changes.Verification
Reproduction: a
Router6and aStandardHost6on one 10 Mb/s link (Ipv6FlatNetworkConfigurator),**.neighbourDiscovery.optimisticDad = true, aPingAppon the host pinging the router's link-local addressfe80::8aa:ff:fe00:1every 0.2 s from t=0, for 3 s of simulated time; NSs read from the host's network-layer dispatcher log.fe80::8aa:ff:fe00:2toff02::1:ff00:1On master the router ignores the NSs at 0-2 s because their target, its own link-local address, is still tentative too (
Target Address is tentative. Ignoring NS.), and address resolution fails at 3 s, when the run ends; with this change resolution starts after both addresses are assigned. The testtests/module/IPv6_ND_no_solicitation_from_tentative_address.testruns this network and checks that no such NS comes before the host'sDAD completedline and that one comes after it; it fails on master and passes with this change.The configurations whose fingerprints change,
inet/hierarchical99IPv6(networklayer.ini),ipv6/mipv6Handoverandipv6/mipv6roamingRoaming, each defer one address resolution at start-up, loggedNo address assigned to the interface yet, address resolution waits for DAD: a host at 0.55 s inhierarchical99, the correspondent node at 1 s, when its pings start, in the two Mobile IPv6 examples. Their ping requests and replies are the same as on master (0 of 1, 108 of 139, 112 of 139). KeepinggetPreferredAddress()as the source for forwarded datagrams leaves the fingerprints and application counters of these twelve configurations as on master; changing it would move them:bgpv4BgpAndOspfv3,BgpDiamondFailover6,BgpIpv6Basic,BgpWithdrawal6GeneralandRestart,ipv6/mipv6RouteOptimizationTwoCNs,ipv6/nclientsETH,ipv6/pmipv6General,manetrouting/gpsrIPv6,MultiIPv6andDynamicIPv6,rip/simpletestIPv6.Release build (
make MODE=releasein the root andtests/module/lib), each suite run on master41eee1d619and with this change; this branch is on master9b4b22258f, which changes no file undersrc,tests,examples,showcases,tutorials,pythonorbin:tests/fingerprint: ./fingerprinttest -s -F tyfipv6/mipv6Handoverandmipv6roamingRoamingamong them compute different values, the other three the same) and 4 rows that passed on master:hierarchical99IPv6inexamples.csvandmipv6-refactoring.csv,ipv6/mipv6Handoverandmipv6roamingRoaminginexamples.csv; with the 4 recorded,./fingerprinttest -s -F tyf -m 'hierarchical99|/ipv6/mipv6/|mipv6roaming'shows only the 3 failures of master among its 15 rows; without-F tyf, the 4 recorded rows pass with every ingredient, and besides the 3 of master, the only failure is thetyfofipv6/mipv6RouteOptimizationTwoCNsinexamples.csv, which fails the same way on mastertests/module: inet_run_module_tests -m release --no-build -l ERRORIeee80211BlockAckVariant_1and the test that is not on this branch; the new test passesThe 5 fingerprint failures of master are rows of
mipv6-refactoring.csvwhose recorded~tNlbfingerprints are stale; this change leaves their recorded values alone. The 62 errors are configurations whose optional features are not built.Ieee80211BlockAckVariant_1fails and passes on master too (it passed in 7 runs after failing in 2, one of them with master'sIpv6NeighbourDiscovery.cc). Of the 290 module failures on master, 274 aretcp_*tests, one is a test that is not on this branch (IPv6_ND_solicitation_ends_address_resolution, #1337), 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; all of them exceptIeee80211BlockAckVariant_1fail with this change as well.Debug build (
make MODE=debugin the root andtests/module/lib, exit 0, no compiler warning inIpv6NeighbourDiscovery.cc):inet_run_module_tests -m debug --no-build -l ERROR -f IPv6_Npasses the new test.Statistical baselines (the separate
statisticsrepository,origin/master8fdf7f5), pairing each scalar these runs record with the baseline scalar of the same module and name, repeated names in order, and comparing the recorded text: on master all are equal for the three configurations whose fingerprints change; with this change 119 of 1452 differ foripv6/mipv6Handoverand 77 of 1709 formipv6roamingRoaming, and none of 13414 forhierarchical99IPv6. Those two belong in a commit to the statistics repository after this merges, naming this one. Not verified by a test, and not reached in the examples above: an NS source chosen when the datagram's source is tentative but another address is assigned, the retransmission check after a Mobile IPv6 handover, and a datagram whose source a sender set (#1295).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/networklayer/icmpv6pass.Relationship to other pull requests
#1340 (#1339) stops Router Advertisements from a tentative link-local address; this is the Neighbor Solicitation counterpart. #1297 holds datagrams with a tentative source in
Ipv6and exempts Neighbour Discovery messages; with this change address resolution produces no NS with a tentative source. #1139, #1162, #1181, #1183, #1244, #1260 and #1340 also change thehierarchical99IPv6rows, and other open pull requests the Mobile IPv6 rows; whichever merges later re-records them. #1322, #1324, #1326, #1328, #1334, #1337 and #1340 also add an entry under "Notable bug fixes" inWHATSNEW; whichever merges later renumbers.