1 /*
<lambda>null2 * Copyright (C) 2017 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 // ktlint does not allow annotating function argument literals inline. Disable the specific rule
17 // since this negatively affects readability.
18 @file:Suppress("ktlint:standard:comment-wrapping")
19
20 package android.net.ip
21
22 import android.annotation.SuppressLint
23 import android.content.Context
24 import android.net.INetd
25 import android.net.InetAddresses.parseNumericAddress
26 import android.net.IpPrefix
27 import android.net.LinkAddress
28 import android.net.LinkProperties
29 import android.net.RouteInfo
30 import android.net.metrics.IpConnectivityLog
31 import android.os.Handler
32 import android.os.HandlerThread
33 import android.os.MessageQueue
34 import android.os.MessageQueue.OnFileDescriptorEventListener
35 import android.stats.connectivity.IpType
36 import android.stats.connectivity.IpType.IPV4
37 import android.stats.connectivity.IpType.IPV6
38 import android.stats.connectivity.NudEventType
39 import android.stats.connectivity.NudEventType.NUD_CONFIRM_FAILED
40 import android.stats.connectivity.NudEventType.NUD_CONFIRM_FAILED_CRITICAL
41 import android.stats.connectivity.NudEventType.NUD_ORGANIC_FAILED
42 import android.stats.connectivity.NudEventType.NUD_ORGANIC_FAILED_CRITICAL
43 import android.stats.connectivity.NudEventType.NUD_POST_ROAMING_FAILED
44 import android.stats.connectivity.NudEventType.NUD_POST_ROAMING_FAILED_CRITICAL
45 import android.stats.connectivity.NudEventType.NUD_POST_ROAMING_MAC_ADDRESS_CHANGED
46 import android.stats.connectivity.NudNeighborType
47 import android.stats.connectivity.NudNeighborType.NUD_NEIGHBOR_BOTH
48 import android.stats.connectivity.NudNeighborType.NUD_NEIGHBOR_DNS
49 import android.stats.connectivity.NudNeighborType.NUD_NEIGHBOR_GATEWAY
50 import android.system.ErrnoException
51 import android.system.OsConstants.EAGAIN
52 import androidx.test.filters.SmallTest
53 import androidx.test.runner.AndroidJUnit4
54 import com.android.net.module.util.InterfaceParams
55 import com.android.net.module.util.SharedLog
56 import com.android.net.module.util.ip.IpNeighborMonitor
57 import com.android.net.module.util.netlink.StructNdMsg.NUD_FAILED
58 import com.android.net.module.util.netlink.StructNdMsg.NUD_PROBE
59 import com.android.net.module.util.netlink.StructNdMsg.NUD_REACHABLE
60 import com.android.net.module.util.netlink.StructNdMsg.NUD_STALE
61 import com.android.networkstack.metrics.IpReachabilityMonitorMetrics
62 import com.android.networkstack.util.NetworkStackUtils.IP_REACHABILITY_IGNORE_ORGANIC_NUD_FAILURE_VERSION
63 import com.android.networkstack.util.NetworkStackUtils.IP_REACHABILITY_MCAST_RESOLICIT_VERSION
64 import com.android.networkstack.util.NetworkStackUtils.IP_REACHABILITY_ROUTER_MAC_CHANGE_FAILURE_ONLY_AFTER_ROAM_VERSION
65 import com.android.testutils.makeNewNeighMessage
66 import com.android.testutils.waitForIdle
67 import java.io.FileDescriptor
68 import java.lang.annotation.ElementType
69 import java.lang.annotation.Repeatable
70 import java.lang.annotation.Retention
71 import java.lang.annotation.RetentionPolicy
72 import java.lang.annotation.Target
73 import java.net.Inet4Address
74 import java.net.Inet6Address
75 import java.net.InetAddress
76 import java.util.concurrent.CompletableFuture
77 import java.util.concurrent.ConcurrentLinkedQueue
78 import java.util.concurrent.TimeUnit
79 import kotlin.test.assertFalse
80 import kotlin.test.assertTrue
81 import kotlin.test.fail
82 import org.junit.After
83 import org.junit.Before
84 import org.junit.Rule
85 import org.junit.Test
86 import org.junit.rules.TestName
87 import org.junit.runner.RunWith
88 import org.mockito.ArgumentCaptor
89 import org.mockito.ArgumentMatchers.any
90 import org.mockito.ArgumentMatchers.anyInt
91 import org.mockito.ArgumentMatchers.anyString
92 import org.mockito.ArgumentMatchers.eq
93 import org.mockito.Mockito.doAnswer
94 import org.mockito.Mockito.doReturn
95 import org.mockito.Mockito.mock
96 import org.mockito.Mockito.never
97 import org.mockito.Mockito.timeout
98 import org.mockito.Mockito.verify
99
100 private const val TEST_TIMEOUT_MS = 10_000L
101
102 private val TEST_IPV4_GATEWAY = parseNumericAddress("192.168.222.3") as Inet4Address
103 private val TEST_IPV6_GATEWAY = parseNumericAddress("2001:db8::1") as Inet6Address
104
105 private val TEST_MAC_1 = "001122334455"
106 private val TEST_MAC_2 = "1122334455aa"
107
108 // IPv4 gateway is also DNS server.
109 private val TEST_IPV4_GATEWAY_DNS = parseNumericAddress("192.168.222.100") as Inet4Address
110
111 private val TEST_IPV4_LINKADDR = LinkAddress("192.168.222.123/24")
112 private val TEST_IPV6_LINKADDR = LinkAddress("2001:db8::123/64")
113
114 private val TEST_IPV6_LINKLOCAL_LINKADDR = LinkAddress("fe80::123/64")
115 private val TEST_IPV6_LINKLOCAL_GATEWAY = parseNumericAddress("fe80::1") as Inet6Address
116 private val TEST_IPV6_LINKLOCAL_SCOPED_GATEWAY = parseNumericAddress("fe80::1%21") as Inet6Address
117 private val TEST_IPV6_LINKLOCAL_GATEWAY2 = parseNumericAddress("fe80::2") as Inet6Address
118 private val TEST_IPV6_LINKLOCAL_SCOPED_GATEWAY2 = parseNumericAddress("fe80::2%22") as Inet6Address
119
120 // DNSes inside IP prefix
121 private val TEST_IPV4_DNS = parseNumericAddress("192.168.222.1") as Inet4Address
122 private val TEST_IPV6_DNS = parseNumericAddress("2001:db8::321") as Inet6Address
123 private val TEST_IPV6_DNS2 = parseNumericAddress("2001:db8::456") as Inet6Address
124
125 private val TEST_IFACE = InterfaceParams("fake0", 21, null)
126
127 @SuppressLint("NewApi")
128 private val TEST_LINK_PROPERTIES = LinkProperties().apply {
129 interfaceName = TEST_IFACE.name
130 addLinkAddress(TEST_IPV4_LINKADDR)
131 addLinkAddress(TEST_IPV6_LINKADDR)
132
133 // Add on link routes
134 addRoute(RouteInfo(TEST_IPV4_LINKADDR, null /* gateway */, TEST_IFACE.name))
135 addRoute(RouteInfo(TEST_IPV6_LINKADDR, null /* gateway */, TEST_IFACE.name))
136
137 // Add default routes
138 addRoute(RouteInfo(IpPrefix(parseNumericAddress("0.0.0.0"), 0), TEST_IPV4_GATEWAY))
139 addRoute(RouteInfo(IpPrefix(parseNumericAddress("::"), 0), TEST_IPV6_GATEWAY))
140
141 addDnsServer(TEST_IPV4_DNS)
142 addDnsServer(TEST_IPV6_DNS)
143 }
144
145 @SuppressLint("NewApi")
<lambda>null146 private val TEST_IPV4_ONLY_LINK_PROPERTIES = LinkProperties().apply {
147 interfaceName = TEST_IFACE.name
148 addLinkAddress(TEST_IPV4_LINKADDR)
149
150 // Add on link routes
151 addRoute(RouteInfo(TEST_IPV4_LINKADDR, null /* gateway */, TEST_IFACE.name))
152
153 // Add default routes
154 addRoute(RouteInfo(IpPrefix(parseNumericAddress("0.0.0.0"), 0), TEST_IPV4_GATEWAY_DNS))
155
156 addDnsServer(TEST_IPV4_GATEWAY_DNS)
157 }
158
159 @SuppressLint("NewApi")
<lambda>null160 private val TEST_IPV6_LINKLOCAL_SCOPED_LINK_PROPERTIES = LinkProperties().apply {
161 interfaceName = TEST_IFACE.name
162 addLinkAddress(TEST_IPV6_LINKADDR)
163 addLinkAddress(TEST_IPV6_LINKLOCAL_LINKADDR)
164
165 // Add on link routes
166 addRoute(RouteInfo(TEST_IPV6_LINKADDR, null /* gateway */, TEST_IFACE.name))
167 addRoute(RouteInfo(TEST_IPV6_LINKLOCAL_LINKADDR, null /* gateway */, TEST_IFACE.name))
168
169 // Add default routes
170 addRoute(RouteInfo(IpPrefix(parseNumericAddress("::"), 0), TEST_IPV6_LINKLOCAL_SCOPED_GATEWAY))
171
172 addDnsServer(TEST_IPV6_DNS)
173 }
174
175 @SuppressLint("NewApi")
<lambda>null176 private val TEST_DUAL_LINK_PROPERTIES = LinkProperties().apply {
177 interfaceName = TEST_IFACE.name
178 addLinkAddress(TEST_IPV4_LINKADDR)
179 addLinkAddress(TEST_IPV6_LINKADDR)
180 addLinkAddress(TEST_IPV6_LINKLOCAL_LINKADDR)
181
182 // Add on link routes
183 addRoute(RouteInfo(TEST_IPV4_LINKADDR, null /* gateway */, TEST_IFACE.name))
184 addRoute(RouteInfo(TEST_IPV6_LINKADDR, null /* gateway */, TEST_IFACE.name))
185 addRoute(RouteInfo(TEST_IPV6_LINKLOCAL_LINKADDR, null /* gateway */, TEST_IFACE.name))
186
187 // Add default routes
188 addRoute(RouteInfo(IpPrefix(parseNumericAddress("0.0.0.0"), 0), TEST_IPV4_GATEWAY))
189 addRoute(RouteInfo(IpPrefix(parseNumericAddress("::"), 0), TEST_IPV6_LINKLOCAL_SCOPED_GATEWAY))
190
191 addDnsServer(TEST_IPV4_DNS)
192 addDnsServer(TEST_IPV6_DNS)
193 addDnsServer(TEST_IPV6_DNS2)
194 }
195
196 /**
197 * Tests for IpReachabilityMonitor.
198 */
199 @RunWith(AndroidJUnit4::class)
200 @SmallTest
201 class IpReachabilityMonitorTest {
202 @get:Rule val mTestName = TestName()
203 private val callback = mock(IpReachabilityMonitor.Callback::class.java)
204 private val dependencies = mock(IpReachabilityMonitor.Dependencies::class.java)
205 private val log = mock(SharedLog::class.java)
206 private val context = mock(Context::class.java)
207 private val netd = mock(INetd::class.java)
208 private val fd = mock(FileDescriptor::class.java)
209 private val metricsLog = mock(IpConnectivityLog::class.java)
210 private val mIpReachabilityMonitorMetrics = mock(IpReachabilityMonitorMetrics::class.java)
211
212 private val handlerThread = HandlerThread(IpReachabilityMonitorTest::class.simpleName)
<lambda>null213 private val handler by lazy { Handler(handlerThread.looper) }
214
215 private lateinit var reachabilityMonitor: IpReachabilityMonitor
216 private lateinit var neighborMonitor: TestIpNeighborMonitor
217
218 @Retention(RetentionPolicy.RUNTIME)
219 @Target(ElementType.METHOD)
220 @Repeatable(FlagArray::class)
221 annotation class Flag(val name: String, val enabled: Boolean)
222
223 @Retention(RetentionPolicy.RUNTIME)
224 @Target(ElementType.METHOD)
225 annotation class FlagArray(val value: Array<Flag>)
226
227 /**
228 * A version of [IpNeighborMonitor] that overrides packet reading from a socket, and instead
229 * allows the test to enqueue test packets via [enqueuePacket].
230 */
231 private class TestIpNeighborMonitor(
232 handler: Handler,
233 log: SharedLog,
234 cb: NeighborEventConsumer,
235 private val fd: FileDescriptor
236 ) : IpNeighborMonitor(handler, log, cb) {
237
238 private val pendingPackets = ConcurrentLinkedQueue<ByteArray>()
239 val msgQueue = mock(MessageQueue::class.java)
240
241 private var eventListener: OnFileDescriptorEventListener? = null
242
createFdnull243 override fun createFd() = fd
244 override fun getMessageQueue() = msgQueue
245
246 fun enqueuePacket(packet: ByteArray) {
247 val listener = eventListener ?: fail("IpNeighborMonitor was not yet started")
248 pendingPackets.add(packet)
249 handler.post {
250 listener.onFileDescriptorEvents(fd, OnFileDescriptorEventListener.EVENT_INPUT)
251 }
252 }
253
readPacketnull254 override fun readPacket(fd: FileDescriptor, packetBuffer: ByteArray): Int {
255 val packet = pendingPackets.poll() ?: throw ErrnoException("No pending packet", EAGAIN)
256 if (packet.size > packetBuffer.size) {
257 fail("Buffer (${packetBuffer.size}) is too small for packet (${packet.size})")
258 }
259 System.arraycopy(packet, 0, packetBuffer, 0, packet.size)
260 return packet.size
261 }
262
onStartnull263 override fun onStart() {
264 super.onStart()
265
266 // Find the file descriptor listener that was registered on the instrumented queue
267 val captor = ArgumentCaptor.forClass(OnFileDescriptorEventListener::class.java)
268 verify(msgQueue).addOnFileDescriptorEventListener(
269 eq(fd),
270 anyInt(),
271 captor.capture()
272 )
273 eventListener = captor.value
274 }
275 }
276
277 @Before
setUpnull278 fun setUp() {
279 doReturn(log).`when`(log).forSubComponent(anyString())
280 doReturn(true).`when`(fd).valid()
281 handlerThread.start()
282
283 doAnswer { inv ->
284 val handler = inv.getArgument<Handler>(0)
285 val log = inv.getArgument<SharedLog>(1)
286 val cb = inv.getArgument<IpNeighborMonitor.NeighborEventConsumer>(2)
287 neighborMonitor = TestIpNeighborMonitor(handler, log, cb, fd)
288 neighborMonitor
289 }.`when`(dependencies).makeIpNeighborMonitor(any(), any(), any())
290 doReturn(mIpReachabilityMonitorMetrics)
291 .`when`(dependencies).getIpReachabilityMonitorMetrics()
292
293 // Set flags based on test method annotations.
294 // Note: because dependencies is a mock, all features that are not specified in flag
295 // annotations are either disabled or chickened out.
296 var testMethod = this::class.java.getMethod(mTestName.methodName)
297 val flags = testMethod.getAnnotationsByType(Flag::class.java)
298 for (f in flags) {
299 doReturn(f.enabled).`when`(dependencies).isFeatureEnabled(any(), eq(f.name))
300 doReturn(f.enabled).`when`(dependencies).isFeatureNotChickenedOut(any(), eq(f.name))
301 }
302
303 val monitorFuture = CompletableFuture<IpReachabilityMonitor>()
304 // IpReachabilityMonitor needs to be started from the handler thread
305 handler.post {
306 monitorFuture.complete(IpReachabilityMonitor(
307 context,
308 TEST_IFACE,
309 handler,
310 log,
311 callback,
312 false /* useMultinetworkPolicyTracker */,
313 dependencies,
314 metricsLog,
315 netd))
316 }
317 reachabilityMonitor = monitorFuture.get(TEST_TIMEOUT_MS, TimeUnit.MILLISECONDS)
318 assertTrue(
319 ::neighborMonitor.isInitialized,
320 "IpReachabilityMonitor did not call makeIpNeighborMonitor"
321 )
322 }
323
324 @After
tearDownnull325 fun tearDown() {
326 // Ensure the handler thread is not accessing the fd while changing its mock
327 handlerThread.waitForIdle(TEST_TIMEOUT_MS)
328 doReturn(false).`when`(fd).valid()
329 handlerThread.quitSafely()
330 }
331
332 @Test
testLoseProvisioning_FirstProbeIsFailednull333 fun testLoseProvisioning_FirstProbeIsFailed() {
334 reachabilityMonitor.updateLinkProperties(TEST_LINK_PROPERTIES)
335
336 // Make the IPv4 DNS as reachable first.
337 neighborMonitor.enqueuePacket(makeNewNeighMessage(TEST_IPV4_DNS, NUD_REACHABLE))
338 handlerThread.waitForIdle(TEST_TIMEOUT_MS)
339
340 neighborMonitor.enqueuePacket(makeNewNeighMessage(TEST_IPV4_DNS, NUD_FAILED))
341 verify(callback, timeout(TEST_TIMEOUT_MS)).notifyLost(
342 anyString(),
343 eq(NUD_ORGANIC_FAILED_CRITICAL)
344 )
345 }
346
347 // Given the flag which ignores the NUD failure from the neighbor that is never reachable
348 // before has been enabled by default, we have to make the neighbor as reachable first and
349 // simulate a NUD failure by making a new NUD_FAILED neighbor message. So change the param
350 // "everReachable" to true always.
runLoseProvisioningTestnull351 private fun runLoseProvisioningTest(
352 newLp: LinkProperties,
353 lostNeighbor: InetAddress,
354 eventType: NudEventType
355 ) {
356 runLoseProvisioningTest(
357 newLp,
358 lostNeighbor,
359 eventType,
360 true, /* everReachable */
361 true /* expectedNotifyLost */
362 )
363 }
364
runLoseProvisioningTestnull365 private fun runLoseProvisioningTest(
366 newLp: LinkProperties,
367 lostNeighbor: InetAddress,
368 eventType: NudEventType,
369 everReachable: Boolean,
370 expectedNotifyLost: Boolean
371 ) {
372 reachabilityMonitor.updateLinkProperties(newLp)
373
374 neighborMonitor.enqueuePacket(makeNewNeighMessage(TEST_IPV4_GATEWAY, NUD_STALE))
375 neighborMonitor.enqueuePacket(makeNewNeighMessage(TEST_IPV6_GATEWAY, NUD_STALE))
376 neighborMonitor.enqueuePacket(makeNewNeighMessage(TEST_IPV4_DNS, NUD_STALE))
377 neighborMonitor.enqueuePacket(makeNewNeighMessage(TEST_IPV6_DNS, NUD_STALE))
378 neighborMonitor.enqueuePacket(
379 makeNewNeighMessage(TEST_IPV6_LINKLOCAL_SCOPED_GATEWAY, NUD_STALE)
380 )
381 neighborMonitor.enqueuePacket(makeNewNeighMessage(TEST_IPV4_GATEWAY_DNS, NUD_STALE))
382
383 // Make all neighbors used in the test as reachable.
384 if (everReachable) {
385 neighborMonitor.enqueuePacket(makeNewNeighMessage(TEST_IPV4_DNS, NUD_REACHABLE))
386 neighborMonitor.enqueuePacket(makeNewNeighMessage(TEST_IPV6_DNS, NUD_REACHABLE))
387 neighborMonitor.enqueuePacket(makeNewNeighMessage(TEST_IPV6_GATEWAY, NUD_REACHABLE))
388 neighborMonitor.enqueuePacket(makeNewNeighMessage(TEST_IPV4_GATEWAY, NUD_REACHABLE))
389 neighborMonitor.enqueuePacket(
390 makeNewNeighMessage(TEST_IPV6_LINKLOCAL_SCOPED_GATEWAY, NUD_REACHABLE)
391 )
392 neighborMonitor.enqueuePacket(makeNewNeighMessage(TEST_IPV4_GATEWAY_DNS, NUD_REACHABLE))
393 }
394
395 neighborMonitor.enqueuePacket(makeNewNeighMessage(lostNeighbor, NUD_PROBE))
396 neighborMonitor.enqueuePacket(makeNewNeighMessage(lostNeighbor, NUD_FAILED))
397 handlerThread.waitForIdle(TEST_TIMEOUT_MS)
398
399 if (expectedNotifyLost) {
400 verify(callback, timeout(TEST_TIMEOUT_MS)).notifyLost(
401 anyString(),
402 eq(eventType)
403 )
404 } else {
405 verify(callback, never()).notifyLost(anyString(), any())
406 }
407 }
408
verifyNudFailureMetricsnull409 private fun verifyNudFailureMetrics(
410 eventType: NudEventType,
411 ipType: IpType,
412 lostNeighborType: NudNeighborType
413 ) {
414 verify(mIpReachabilityMonitorMetrics, timeout(TEST_TIMEOUT_MS)).setNudIpType(eq(ipType))
415 verify(mIpReachabilityMonitorMetrics, timeout(TEST_TIMEOUT_MS))
416 .setNudEventType(eq(eventType))
417 verify(mIpReachabilityMonitorMetrics, timeout(TEST_TIMEOUT_MS))
418 .setNudNeighborType(eq(lostNeighborType))
419 }
420
verifyNudFailureMetricsNotReportednull421 private fun verifyNudFailureMetricsNotReported(
422 ) {
423 verify(mIpReachabilityMonitorMetrics, never()).setNudIpType(any())
424 verify(mIpReachabilityMonitorMetrics, never()).setNudEventType(any())
425 verify(mIpReachabilityMonitorMetrics, never()).setNudNeighborType(any())
426 }
427
428 // Verify if the notifyLost will be called when one neighbor has lost but it's still
429 // provisioned.
runLoseNeighborStillProvisionedTestnull430 private fun runLoseNeighborStillProvisionedTest(
431 newLp: LinkProperties,
432 lostNeighbor: InetAddress,
433 eventType: NudEventType,
434 ipType: IpType,
435 lostNeighborType: NudNeighborType
436 ) {
437 reachabilityMonitor.updateLinkProperties(newLp)
438
439 neighborMonitor.enqueuePacket(makeNewNeighMessage(lostNeighbor, NUD_FAILED))
440 handlerThread.waitForIdle(TEST_TIMEOUT_MS)
441 verify(callback, never()).notifyLost(anyString(), any(NudEventType::class.java))
442 verifyNudFailureMetrics(eventType, ipType, lostNeighborType)
443 }
444
prepareNeighborReachableButMacAddrChangedTestnull445 private fun prepareNeighborReachableButMacAddrChangedTest(
446 newLp: LinkProperties,
447 neighbor: InetAddress,
448 macaddr: String
449 ) {
450 reachabilityMonitor.updateLinkProperties(newLp)
451
452 neighborMonitor.enqueuePacket(makeNewNeighMessage(neighbor, NUD_REACHABLE, macaddr))
453 handlerThread.waitForIdle(TEST_TIMEOUT_MS)
454 verify(callback, never()).notifyLost(
455 anyString(),
456 any(NudEventType::class.java)
457 )
458 }
459
460 @Test
testLoseProvisioning_Ipv4DnsLostnull461 fun testLoseProvisioning_Ipv4DnsLost() {
462 runLoseProvisioningTest(TEST_LINK_PROPERTIES, TEST_IPV4_DNS, NUD_ORGANIC_FAILED_CRITICAL)
463 }
464
465 @Test
testLoseProvisioning_Ipv6DnsLostnull466 fun testLoseProvisioning_Ipv6DnsLost() {
467 runLoseProvisioningTest(TEST_LINK_PROPERTIES, TEST_IPV6_DNS, NUD_ORGANIC_FAILED_CRITICAL)
468 }
469
470 @Test
testLoseProvisioning_Ipv4GatewayLostnull471 fun testLoseProvisioning_Ipv4GatewayLost() {
472 runLoseProvisioningTest(
473 TEST_LINK_PROPERTIES,
474 TEST_IPV4_GATEWAY,
475 NUD_ORGANIC_FAILED_CRITICAL
476 )
477 }
478
479 @Test
testLoseProvisioning_Ipv6GatewayLostnull480 fun testLoseProvisioning_Ipv6GatewayLost() {
481 runLoseProvisioningTest(
482 TEST_LINK_PROPERTIES,
483 TEST_IPV6_GATEWAY,
484 NUD_ORGANIC_FAILED_CRITICAL
485 )
486 }
487
488 @Test
489 @Flag(name = IP_REACHABILITY_IGNORE_ORGANIC_NUD_FAILURE_VERSION, enabled = true)
testLoseProvisioning_ignoreOrganicIpv4DnsLostnull490 fun testLoseProvisioning_ignoreOrganicIpv4DnsLost() {
491 runLoseProvisioningTest(
492 TEST_LINK_PROPERTIES,
493 TEST_IPV4_DNS,
494 NUD_ORGANIC_FAILED_CRITICAL,
495 false /* everReachable */,
496 false /* expectedNotifyLost */
497 )
498 }
499
500 @Test
501 @Flag(name = IP_REACHABILITY_IGNORE_ORGANIC_NUD_FAILURE_VERSION, enabled = true)
testLoseProvisioning_ignoreOrganicIpv6DnsLostnull502 fun testLoseProvisioning_ignoreOrganicIpv6DnsLost() {
503 runLoseProvisioningTest(
504 TEST_LINK_PROPERTIES,
505 TEST_IPV6_DNS,
506 NUD_ORGANIC_FAILED_CRITICAL,
507 false /* everReachable */,
508 false /* expectedNotifyLost */
509 )
510 }
511
512 @Test
513 @Flag(name = IP_REACHABILITY_IGNORE_ORGANIC_NUD_FAILURE_VERSION, enabled = true)
testLoseProvisioning_ignoreOrganicIpv4GatewayLostnull514 fun testLoseProvisioning_ignoreOrganicIpv4GatewayLost() {
515 runLoseProvisioningTest(
516 TEST_LINK_PROPERTIES,
517 TEST_IPV4_GATEWAY,
518 NUD_ORGANIC_FAILED_CRITICAL,
519 false /* everReachable */,
520 false /* expectedNotifyLost */
521 )
522 }
523
524 @Test
525 @Flag(name = IP_REACHABILITY_IGNORE_ORGANIC_NUD_FAILURE_VERSION, enabled = true)
testLoseProvisioning_ignoreOrganicIpv6GatewayLostnull526 fun testLoseProvisioning_ignoreOrganicIpv6GatewayLost() {
527 runLoseProvisioningTest(
528 TEST_LINK_PROPERTIES,
529 TEST_IPV6_GATEWAY,
530 NUD_ORGANIC_FAILED_CRITICAL,
531 false /* everReachable */,
532 false /* expectedNotifyLost */
533 )
534 }
535
536 @Test
testLoseProvisioning_ignoreNeverReachableIpv6GatewayLostnull537 fun testLoseProvisioning_ignoreNeverReachableIpv6GatewayLost() {
538 runLoseProvisioningTest(
539 TEST_LINK_PROPERTIES,
540 TEST_IPV6_GATEWAY,
541 NUD_ORGANIC_FAILED_CRITICAL,
542 false /* everReachable */,
543 false /* expectedNotifyLost */
544 )
545 }
546
547 @Test
testLoseProvisioning_ignoreNeverReachableIpv6DnsLostnull548 fun testLoseProvisioning_ignoreNeverReachableIpv6DnsLost() {
549 runLoseProvisioningTest(
550 TEST_LINK_PROPERTIES,
551 TEST_IPV6_DNS,
552 NUD_ORGANIC_FAILED_CRITICAL,
553 false /* everReachable */,
554 false /* expectedNotifyLost */
555 )
556 }
557
558 @Test
testLoseProvisioning_notIgnoreEverReachableIpv6GatewayLostnull559 fun testLoseProvisioning_notIgnoreEverReachableIpv6GatewayLost() {
560 runLoseProvisioningTest(
561 TEST_LINK_PROPERTIES,
562 TEST_IPV6_GATEWAY,
563 NUD_ORGANIC_FAILED_CRITICAL,
564 true /* everReachable */,
565 true /* expectedNotifyLost */
566 )
567 }
568
569 @Test
testLoseProvisioning_notIgnoreEverReachableIpv6DnsLostnull570 fun testLoseProvisioning_notIgnoreEverReachableIpv6DnsLost() {
571 runLoseProvisioningTest(
572 TEST_LINK_PROPERTIES,
573 TEST_IPV6_DNS,
574 NUD_ORGANIC_FAILED_CRITICAL,
575 true /* everReachable */,
576 true /* expectedNotifyLost */
577 )
578 }
579
580 @Test
testLoseProvisioning_ignoreNeverReachableIpv4DnsLostnull581 fun testLoseProvisioning_ignoreNeverReachableIpv4DnsLost() {
582 runLoseProvisioningTest(
583 TEST_LINK_PROPERTIES,
584 TEST_IPV4_DNS,
585 NUD_ORGANIC_FAILED_CRITICAL,
586 false /* everReachable */,
587 false /* expectedNotifyLost */
588 )
589 }
590
591 @Test
testLoseProvisioning_notIgnoreEverReachableIpv4GatewayLostnull592 fun testLoseProvisioning_notIgnoreEverReachableIpv4GatewayLost() {
593 runLoseProvisioningTest(
594 TEST_LINK_PROPERTIES,
595 TEST_IPV4_GATEWAY,
596 NUD_ORGANIC_FAILED_CRITICAL,
597 true /* everReachable */,
598 true /* expectedNotifyLost */
599 )
600 }
601
602 @Test
testLoseProvisioning_notIgnoreEverReachableIpv4DnsLostnull603 fun testLoseProvisioning_notIgnoreEverReachableIpv4DnsLost() {
604 runLoseProvisioningTest(
605 TEST_LINK_PROPERTIES,
606 TEST_IPV4_DNS,
607 NUD_ORGANIC_FAILED_CRITICAL,
608 true /* everReachable */,
609 true /* expectedNotifyLost */
610 )
611 }
612
613 @Test
testLoseProvisioning_ignoreNeverReachableIpv6GatewayLost_withTwoIPv6DnsServersnull614 fun testLoseProvisioning_ignoreNeverReachableIpv6GatewayLost_withTwoIPv6DnsServers() {
615 reachabilityMonitor.updateLinkProperties(TEST_DUAL_LINK_PROPERTIES)
616
617 // IPv6 default router is never reachable, but two DNS servers do.
618 neighborMonitor.enqueuePacket(makeNewNeighMessage(TEST_IPV4_DNS, NUD_REACHABLE))
619 neighborMonitor.enqueuePacket(makeNewNeighMessage(TEST_IPV4_GATEWAY, NUD_REACHABLE))
620 neighborMonitor.enqueuePacket(makeNewNeighMessage(TEST_IPV6_DNS, NUD_REACHABLE))
621 neighborMonitor.enqueuePacket(makeNewNeighMessage(TEST_IPV6_DNS2, NUD_REACHABLE))
622
623 // Push a NUD_FAILED event to IPv6 default router, this event should not trigger
624 // onReachabilityFailure callback given it's never reachable.
625 neighborMonitor.enqueuePacket(makeNewNeighMessage(TEST_IPV6_GATEWAY, NUD_PROBE))
626 neighborMonitor.enqueuePacket(makeNewNeighMessage(TEST_IPV6_GATEWAY, NUD_FAILED))
627 handlerThread.waitForIdle(TEST_TIMEOUT_MS)
628
629 verify(callback, never()).notifyLost(anyString(), any())
630
631 // Then another NUD_FAILED from one of DNS servers, this event should not trigger
632 // onReachabilityFailure callback either.
633 neighborMonitor.enqueuePacket(makeNewNeighMessage(TEST_IPV6_DNS, NUD_PROBE))
634 neighborMonitor.enqueuePacket(makeNewNeighMessage(TEST_IPV6_DNS, NUD_FAILED))
635 handlerThread.waitForIdle(TEST_TIMEOUT_MS)
636
637 verify(callback, never()).notifyLost(anyString(), any())
638
639 // Then we lost all IPv6 DNS servers, onReachabilityFailure callback should be triggered.
640 neighborMonitor.enqueuePacket(makeNewNeighMessage(TEST_IPV6_DNS2, NUD_PROBE))
641 neighborMonitor.enqueuePacket(makeNewNeighMessage(TEST_IPV6_DNS2, NUD_FAILED))
642 handlerThread.waitForIdle(TEST_TIMEOUT_MS)
643
644 verify(callback, timeout(TEST_TIMEOUT_MS)).notifyLost(
645 anyString(),
646 eq(NUD_ORGANIC_FAILED_CRITICAL)
647 )
648 }
649
650 @Test
testLoseProvisioning_ignoreNeverReachableIpv6DnsLost_withTwoIPv6Routesnull651 fun testLoseProvisioning_ignoreNeverReachableIpv6DnsLost_withTwoIPv6Routes() {
652 val TEST_DUAL_IPV6_ROUTERS_LINK_PROPERTIES = LinkProperties().apply {
653 interfaceName = TEST_IFACE.name
654 addLinkAddress(TEST_IPV4_LINKADDR)
655 addLinkAddress(TEST_IPV6_LINKADDR)
656 addLinkAddress(TEST_IPV6_LINKLOCAL_LINKADDR)
657
658 // Add on link routes
659 addRoute(RouteInfo(TEST_IPV4_LINKADDR, null /* gateway */, TEST_IFACE.name))
660 addRoute(RouteInfo(TEST_IPV6_LINKADDR, null /* gateway */, TEST_IFACE.name))
661 addRoute(RouteInfo(TEST_IPV6_LINKLOCAL_LINKADDR, null /* gateway */, TEST_IFACE.name))
662
663 // Add default routes: one IPv4 default route and two IPv6 default routes.
664 addRoute(RouteInfo(IpPrefix(parseNumericAddress("0.0.0.0"), 0), TEST_IPV4_GATEWAY))
665 addRoute(
666 RouteInfo(
667 IpPrefix(parseNumericAddress("::"), 0),
668 TEST_IPV6_LINKLOCAL_SCOPED_GATEWAY
669 )
670 )
671 addRoute(
672 RouteInfo(
673 IpPrefix(parseNumericAddress("::"), 0),
674 TEST_IPV6_LINKLOCAL_SCOPED_GATEWAY2
675 )
676 )
677
678 addDnsServer(TEST_IPV4_DNS)
679 addDnsServer(TEST_IPV6_DNS)
680 }
681
682 reachabilityMonitor.updateLinkProperties(TEST_DUAL_IPV6_ROUTERS_LINK_PROPERTIES)
683
684 // IPv6 DNS is never reachable, but two default gateways do.
685 neighborMonitor.enqueuePacket(makeNewNeighMessage(TEST_IPV4_DNS, NUD_REACHABLE))
686 neighborMonitor.enqueuePacket(makeNewNeighMessage(TEST_IPV4_GATEWAY, NUD_REACHABLE))
687 neighborMonitor.enqueuePacket(
688 makeNewNeighMessage(TEST_IPV6_LINKLOCAL_GATEWAY, NUD_REACHABLE)
689 )
690 neighborMonitor.enqueuePacket(
691 makeNewNeighMessage(TEST_IPV6_LINKLOCAL_GATEWAY2, NUD_REACHABLE)
692 )
693
694 // Push a NUD_FAILED event to IPv6 DNS server, this event should not trigger
695 // onReachabilityFailure callback given it's never reachable.
696 neighborMonitor.enqueuePacket(makeNewNeighMessage(TEST_IPV6_DNS, NUD_PROBE))
697 neighborMonitor.enqueuePacket(makeNewNeighMessage(TEST_IPV6_DNS, NUD_FAILED))
698 handlerThread.waitForIdle(TEST_TIMEOUT_MS)
699
700 verify(callback, never()).notifyLost(anyString(), any())
701
702 // Then another NUD_FAILED from one of IPv6 gateways, this event should not trigger
703 // onReachabilityFailure callback either.
704 neighborMonitor.enqueuePacket(makeNewNeighMessage(TEST_IPV6_LINKLOCAL_GATEWAY, NUD_PROBE))
705 neighborMonitor.enqueuePacket(makeNewNeighMessage(TEST_IPV6_LINKLOCAL_GATEWAY, NUD_FAILED))
706 handlerThread.waitForIdle(TEST_TIMEOUT_MS)
707
708 verify(callback, never()).notifyLost(anyString(), any())
709
710 // Then we lost all IPv6 gateways, onReachabilityFailure callback should be triggered.
711 neighborMonitor.enqueuePacket(makeNewNeighMessage(TEST_IPV6_LINKLOCAL_GATEWAY2, NUD_PROBE))
712 neighborMonitor.enqueuePacket(makeNewNeighMessage(TEST_IPV6_LINKLOCAL_GATEWAY2, NUD_FAILED))
713 handlerThread.waitForIdle(TEST_TIMEOUT_MS)
714
715 verify(callback, timeout(TEST_TIMEOUT_MS)).notifyLost(
716 anyString(),
717 eq(NUD_ORGANIC_FAILED_CRITICAL)
718 )
719 }
720
runNudProbeFailureMetricsTestnull721 private fun runNudProbeFailureMetricsTest(
722 lp: LinkProperties,
723 lostNeighbor: InetAddress,
724 eventType: NudEventType,
725 ipType: IpType,
726 lostNeighborType: NudNeighborType
727 ) {
728 runLoseProvisioningTest(lp, lostNeighbor, eventType)
729 verifyNudFailureMetrics(eventType, ipType, lostNeighborType)
730 }
731
732 @Test
testNudProbeFailedMetrics_Ipv6GatewayLostPostRoamingnull733 fun testNudProbeFailedMetrics_Ipv6GatewayLostPostRoaming() {
734 reachabilityMonitor.probeAll(true /* dueToRoam */)
735 runNudProbeFailureMetricsTest(
736 TEST_LINK_PROPERTIES,
737 TEST_IPV6_GATEWAY,
738 NUD_POST_ROAMING_FAILED_CRITICAL,
739 IPV6,
740 NUD_NEIGHBOR_GATEWAY
741 )
742 }
743
744 @Test
testNudProbeFailedMetrics_Ipv4GatewayLostPostRoamingnull745 fun testNudProbeFailedMetrics_Ipv4GatewayLostPostRoaming() {
746 reachabilityMonitor.probeAll(true /* dueToRoam */)
747 runNudProbeFailureMetricsTest(
748 TEST_LINK_PROPERTIES,
749 TEST_IPV4_GATEWAY,
750 NUD_POST_ROAMING_FAILED_CRITICAL,
751 IPV4,
752 NUD_NEIGHBOR_GATEWAY
753 )
754 }
755
756 @Test
testNudProbeFailedMetrics_Ipv6DnsLostPostRoamingnull757 fun testNudProbeFailedMetrics_Ipv6DnsLostPostRoaming() {
758 reachabilityMonitor.probeAll(true /* dueToRoam */)
759 runNudProbeFailureMetricsTest(
760 TEST_LINK_PROPERTIES,
761 TEST_IPV6_DNS,
762 NUD_POST_ROAMING_FAILED_CRITICAL,
763 IPV6,
764 NUD_NEIGHBOR_DNS
765 )
766 }
767
768 @Test
testNudProbeFailedMetrics_Ipv4DnsLostPostRoamingnull769 fun testNudProbeFailedMetrics_Ipv4DnsLostPostRoaming() {
770 reachabilityMonitor.probeAll(true /* dueToRoam */)
771 runNudProbeFailureMetricsTest(
772 TEST_LINK_PROPERTIES,
773 TEST_IPV4_DNS,
774 NUD_POST_ROAMING_FAILED_CRITICAL,
775 IPV4,
776 NUD_NEIGHBOR_DNS
777 )
778 }
779
780 @Test
testNudProbeFailedMetrics_IPv4BothGatewayAndDnsLostPostRoamingnull781 fun testNudProbeFailedMetrics_IPv4BothGatewayAndDnsLostPostRoaming() {
782 reachabilityMonitor.probeAll(true /* dueToRoam */)
783 runNudProbeFailureMetricsTest(
784 TEST_IPV4_ONLY_LINK_PROPERTIES,
785 TEST_IPV4_GATEWAY_DNS,
786 NUD_POST_ROAMING_FAILED_CRITICAL,
787 IPV4,
788 NUD_NEIGHBOR_BOTH
789 )
790 }
791
792 @Test
testNudProbeFailedMetrics_IPv6LinklocalScopedGatewayLostPostRoamingnull793 fun testNudProbeFailedMetrics_IPv6LinklocalScopedGatewayLostPostRoaming() {
794 reachabilityMonitor.probeAll(true /* dueToRoam */)
795 runNudProbeFailureMetricsTest(
796 TEST_IPV6_LINKLOCAL_SCOPED_LINK_PROPERTIES,
797 TEST_IPV6_LINKLOCAL_SCOPED_GATEWAY,
798 NUD_POST_ROAMING_FAILED_CRITICAL,
799 IPV6,
800 NUD_NEIGHBOR_GATEWAY
801 )
802 }
803
804 @Test
testNudProbeFailedMetrics_Ipv6GatewayLostAfterConfirmnull805 fun testNudProbeFailedMetrics_Ipv6GatewayLostAfterConfirm() {
806 reachabilityMonitor.probeAll(false /* dueToRoam */)
807 runNudProbeFailureMetricsTest(
808 TEST_LINK_PROPERTIES,
809 TEST_IPV6_GATEWAY,
810 NUD_CONFIRM_FAILED_CRITICAL,
811 IPV6,
812 NUD_NEIGHBOR_GATEWAY
813 )
814 }
815
816 @Test
testNudProbeFailedMetrics_Ipv4GatewayLostAfterConfirmnull817 fun testNudProbeFailedMetrics_Ipv4GatewayLostAfterConfirm() {
818 reachabilityMonitor.probeAll(false /* dueToRoam */)
819 runNudProbeFailureMetricsTest(
820 TEST_LINK_PROPERTIES,
821 TEST_IPV4_GATEWAY,
822 NUD_CONFIRM_FAILED_CRITICAL,
823 IPV4,
824 NUD_NEIGHBOR_GATEWAY
825 )
826 }
827
828 @Test
testNudProbeFailedMetrics_Ipv6DnsLostAfterConfirmnull829 fun testNudProbeFailedMetrics_Ipv6DnsLostAfterConfirm() {
830 reachabilityMonitor.probeAll(false /* dueToRoam */)
831 runNudProbeFailureMetricsTest(
832 TEST_LINK_PROPERTIES,
833 TEST_IPV6_DNS,
834 NUD_CONFIRM_FAILED_CRITICAL,
835 IPV6,
836 NUD_NEIGHBOR_DNS
837 )
838 }
839
840 @Test
testNudProbeFailedMetrics_Ipv4DnsLostAfterConfirmnull841 fun testNudProbeFailedMetrics_Ipv4DnsLostAfterConfirm() {
842 reachabilityMonitor.probeAll(false /* dueToRoam */)
843 runNudProbeFailureMetricsTest(
844 TEST_LINK_PROPERTIES,
845 TEST_IPV4_DNS,
846 NUD_CONFIRM_FAILED_CRITICAL,
847 IPV4,
848 NUD_NEIGHBOR_DNS
849 )
850 }
851
852 @Test
testNudProbeFailedMetrics_IPv4BothGatewayAndDnsLostAfterConfirmnull853 fun testNudProbeFailedMetrics_IPv4BothGatewayAndDnsLostAfterConfirm() {
854 reachabilityMonitor.probeAll(false /* dueToRoam */)
855 runNudProbeFailureMetricsTest(
856 TEST_IPV4_ONLY_LINK_PROPERTIES,
857 TEST_IPV4_GATEWAY_DNS,
858 NUD_CONFIRM_FAILED_CRITICAL,
859 IPV4,
860 NUD_NEIGHBOR_BOTH
861 )
862 }
863
864 @Test
testNudProbeFailedMetrics_IPv6LinklocalScopedGatewayLostAfterConfirmnull865 fun testNudProbeFailedMetrics_IPv6LinklocalScopedGatewayLostAfterConfirm() {
866 reachabilityMonitor.probeAll(false /* dueToRoam */)
867 runNudProbeFailureMetricsTest(
868 TEST_IPV6_LINKLOCAL_SCOPED_LINK_PROPERTIES,
869 TEST_IPV6_LINKLOCAL_SCOPED_GATEWAY,
870 NUD_CONFIRM_FAILED_CRITICAL,
871 IPV6,
872 NUD_NEIGHBOR_GATEWAY
873 )
874 }
875
876 @Test
testNudProbeFailedMetrics_IPv6GatewayLostOrganicnull877 fun testNudProbeFailedMetrics_IPv6GatewayLostOrganic() {
878 runNudProbeFailureMetricsTest(
879 TEST_LINK_PROPERTIES,
880 TEST_IPV6_GATEWAY,
881 NUD_ORGANIC_FAILED_CRITICAL,
882 IPV6,
883 NUD_NEIGHBOR_GATEWAY
884 )
885 }
886
887 @Test
testNudProbeFailedMetrics_IPv4GatewayLostOrganicnull888 fun testNudProbeFailedMetrics_IPv4GatewayLostOrganic() {
889 runNudProbeFailureMetricsTest(
890 TEST_LINK_PROPERTIES,
891 TEST_IPV4_GATEWAY,
892 NUD_ORGANIC_FAILED_CRITICAL,
893 IPV4,
894 NUD_NEIGHBOR_GATEWAY
895 )
896 }
897
898 @Test
testNudProbeFailedMetrics_IPv6DnsLostOrganicnull899 fun testNudProbeFailedMetrics_IPv6DnsLostOrganic() {
900 runNudProbeFailureMetricsTest(
901 TEST_LINK_PROPERTIES,
902 TEST_IPV6_DNS,
903 NUD_ORGANIC_FAILED_CRITICAL,
904 IPV6,
905 NUD_NEIGHBOR_DNS
906 )
907 }
908
909 @Test
testNudProbeFailedMetrics_IPv4DnsLostOrganicnull910 fun testNudProbeFailedMetrics_IPv4DnsLostOrganic() {
911 runNudProbeFailureMetricsTest(
912 TEST_LINK_PROPERTIES,
913 TEST_IPV4_DNS,
914 NUD_ORGANIC_FAILED_CRITICAL,
915 IPV4,
916 NUD_NEIGHBOR_DNS
917 )
918 }
919
920 @Test
testNudProbeFailedMetrics_IPv4BothGatewayAndDnsLostOrganicnull921 fun testNudProbeFailedMetrics_IPv4BothGatewayAndDnsLostOrganic() {
922 runNudProbeFailureMetricsTest(
923 TEST_IPV4_ONLY_LINK_PROPERTIES,
924 TEST_IPV4_GATEWAY_DNS,
925 NUD_ORGANIC_FAILED_CRITICAL,
926 IPV4,
927 NUD_NEIGHBOR_BOTH
928 )
929 }
930
931 @Test
testNudProbeFailedMetrics_IPv6LinklocalScopedGatewayLostOrganicnull932 fun testNudProbeFailedMetrics_IPv6LinklocalScopedGatewayLostOrganic() {
933 runNudProbeFailureMetricsTest(
934 TEST_IPV6_LINKLOCAL_SCOPED_LINK_PROPERTIES,
935 TEST_IPV6_LINKLOCAL_SCOPED_GATEWAY,
936 NUD_ORGANIC_FAILED_CRITICAL,
937 IPV6,
938 NUD_NEIGHBOR_GATEWAY
939 )
940 }
941
942 @Test
testNudProbeFailedMetrics_IPv6OneDnsNeighborLostPostRoamingnull943 fun testNudProbeFailedMetrics_IPv6OneDnsNeighborLostPostRoaming() {
944 reachabilityMonitor.probeAll(true /* dueToRoam */)
945 runLoseNeighborStillProvisionedTest(
946 TEST_DUAL_LINK_PROPERTIES,
947 TEST_IPV6_DNS,
948 NUD_POST_ROAMING_FAILED,
949 IPV6,
950 NUD_NEIGHBOR_DNS
951 )
952 }
953
954 @Test
testNudProbeFailedMetrics_IPv6OneDnsNeighborLostAfterConfirmnull955 fun testNudProbeFailedMetrics_IPv6OneDnsNeighborLostAfterConfirm() {
956 reachabilityMonitor.probeAll(false /* dueToRoam */)
957 runLoseNeighborStillProvisionedTest(
958 TEST_DUAL_LINK_PROPERTIES,
959 TEST_IPV6_DNS,
960 NUD_CONFIRM_FAILED,
961 IPV6,
962 NUD_NEIGHBOR_DNS
963 )
964 }
965
966 @Test
testNudProbeFailedMetrics_IPv6OneDnsNeighborLostOrganicnull967 fun testNudProbeFailedMetrics_IPv6OneDnsNeighborLostOrganic() {
968 runLoseNeighborStillProvisionedTest(
969 TEST_DUAL_LINK_PROPERTIES,
970 TEST_IPV6_DNS,
971 NUD_ORGANIC_FAILED,
972 IPV6,
973 NUD_NEIGHBOR_DNS
974 )
975 }
976
977 @Test
testNudProbeFailedMetrics_multipleProbesFromRoamFirstnull978 fun testNudProbeFailedMetrics_multipleProbesFromRoamFirst() {
979 reachabilityMonitor.probeAll(true /* dueToRoam */)
980 handlerThread.waitForIdle(TEST_TIMEOUT_MS)
981 Thread.sleep(2)
982 reachabilityMonitor.probeAll(false /* dueToRoam */)
983 runLoseProvisioningTest(
984 TEST_LINK_PROPERTIES,
985 TEST_IPV6_GATEWAY,
986 NUD_POST_ROAMING_FAILED_CRITICAL
987 )
988
989 verifyNudFailureMetrics(NUD_POST_ROAMING_FAILED_CRITICAL, IPV6, NUD_NEIGHBOR_GATEWAY)
990 }
991
992 @Test
testNudProbeFailedMetrics_multipleProbesFromConfirmFirstnull993 fun testNudProbeFailedMetrics_multipleProbesFromConfirmFirst() {
994 reachabilityMonitor.probeAll(false /* dueToRoam */)
995 handlerThread.waitForIdle(TEST_TIMEOUT_MS)
996 Thread.sleep(2)
997 reachabilityMonitor.probeAll(true /* dueToRoam */)
998 runLoseProvisioningTest(
999 TEST_LINK_PROPERTIES,
1000 TEST_IPV6_GATEWAY,
1001 NUD_CONFIRM_FAILED_CRITICAL
1002 )
1003
1004 verifyNudFailureMetrics(NUD_CONFIRM_FAILED_CRITICAL, IPV6, NUD_NEIGHBOR_GATEWAY)
1005 }
1006
probeWithNeighborEventnull1007 private fun probeWithNeighborEvent(dueToRoam: Boolean, neighbor: InetAddress, macaddr: String) {
1008 reachabilityMonitor.probeAll(dueToRoam)
1009 neighborMonitor.enqueuePacket(makeNewNeighMessage(neighbor, NUD_PROBE, macaddr))
1010 }
1011
verifyNudMacAddrChangednull1012 private fun verifyNudMacAddrChanged(
1013 neighbor: InetAddress,
1014 eventType: NudEventType,
1015 ipType: IpType
1016 ) {
1017 neighborMonitor.enqueuePacket(makeNewNeighMessage(neighbor, NUD_REACHABLE, TEST_MAC_2))
1018 verify(callback, timeout(TEST_TIMEOUT_MS)).notifyLost(
1019 anyString(),
1020 eq(eventType)
1021 )
1022 verifyNudFailureMetrics(eventType, ipType, NUD_NEIGHBOR_GATEWAY)
1023 }
1024
verifyNudMacAddrChangeNotReportednull1025 private fun verifyNudMacAddrChangeNotReported(
1026 neighbor: InetAddress,
1027 ) {
1028 neighborMonitor.enqueuePacket(makeNewNeighMessage(neighbor, NUD_REACHABLE, TEST_MAC_2))
1029 verify(callback, never()).notifyLost(anyString(), any())
1030 verifyNudFailureMetricsNotReported()
1031 }
1032
1033 @Test
1034 @Flag(name = IP_REACHABILITY_MCAST_RESOLICIT_VERSION, true)
1035 @Flag(name = IP_REACHABILITY_ROUTER_MAC_CHANGE_FAILURE_ONLY_AFTER_ROAM_VERSION, enabled = true)
testNudProbeFailedMetrics_defaultIPv6GatewayMacAddrChangedAfterRoamingnull1036 fun testNudProbeFailedMetrics_defaultIPv6GatewayMacAddrChangedAfterRoaming() {
1037 prepareNeighborReachableButMacAddrChangedTest(
1038 TEST_LINK_PROPERTIES,
1039 TEST_IPV6_GATEWAY,
1040 TEST_MAC_1
1041 )
1042 probeWithNeighborEvent(true /* dueToRoam */, TEST_IPV6_GATEWAY, TEST_MAC_1)
1043 verifyNudMacAddrChanged(TEST_IPV6_GATEWAY, NUD_POST_ROAMING_MAC_ADDRESS_CHANGED, IPV6)
1044 }
1045
1046 @Test
1047 @Flag(name = IP_REACHABILITY_MCAST_RESOLICIT_VERSION, true)
1048 @Flag(name = IP_REACHABILITY_ROUTER_MAC_CHANGE_FAILURE_ONLY_AFTER_ROAM_VERSION, enabled = true)
testNudProbeFailedMetrics_defaultIPv4GatewayMacAddrChangedAfterRoamingnull1049 fun testNudProbeFailedMetrics_defaultIPv4GatewayMacAddrChangedAfterRoaming() {
1050 prepareNeighborReachableButMacAddrChangedTest(
1051 TEST_LINK_PROPERTIES,
1052 TEST_IPV4_GATEWAY,
1053 TEST_MAC_1
1054 )
1055
1056 probeWithNeighborEvent(true /* dueToRoam */, TEST_IPV4_GATEWAY, TEST_MAC_1)
1057 verifyNudMacAddrChanged(TEST_IPV4_GATEWAY, NUD_POST_ROAMING_MAC_ADDRESS_CHANGED, IPV4)
1058 }
1059
1060 @Test
1061 @Flag(name = IP_REACHABILITY_MCAST_RESOLICIT_VERSION, true)
1062 @Flag(name = IP_REACHABILITY_ROUTER_MAC_CHANGE_FAILURE_ONLY_AFTER_ROAM_VERSION, enabled = true)
testNudProbeFailedMetrics_defaultIPv6GatewayMacAddrChangedAfterConfirmnull1063 fun testNudProbeFailedMetrics_defaultIPv6GatewayMacAddrChangedAfterConfirm() {
1064 prepareNeighborReachableButMacAddrChangedTest(
1065 TEST_LINK_PROPERTIES,
1066 TEST_IPV6_GATEWAY,
1067 TEST_MAC_1
1068 )
1069
1070 reachabilityMonitor.probeAll(false /* dueToRoam */)
1071 verifyNudMacAddrChangeNotReported(TEST_IPV6_GATEWAY)
1072 }
1073
1074 @Test
1075 @Flag(name = IP_REACHABILITY_MCAST_RESOLICIT_VERSION, true)
1076 @Flag(name = IP_REACHABILITY_ROUTER_MAC_CHANGE_FAILURE_ONLY_AFTER_ROAM_VERSION, enabled = true)
testNudProbeFailedMetrics_defaultIPv6GatewayMacAddrChangedAfterOrganicnull1077 fun testNudProbeFailedMetrics_defaultIPv6GatewayMacAddrChangedAfterOrganic() {
1078 prepareNeighborReachableButMacAddrChangedTest(
1079 TEST_LINK_PROPERTIES,
1080 TEST_IPV6_GATEWAY,
1081 TEST_MAC_1
1082 )
1083
1084 verifyNudMacAddrChangeNotReported(TEST_IPV6_GATEWAY)
1085 }
1086
1087 @SuppressLint("NewApi")
1088 @Test
testIsOnLinknull1089 fun testIsOnLink() {
1090 val routes: List<RouteInfo> = listOf(
1091 RouteInfo(
1092 IpPrefix(parseNumericAddress("192.168.0.0"), 16),
1093 null /* gateway */,
1094 null /* iface */,
1095 RouteInfo.RTN_THROW
1096 ),
1097 RouteInfo(IpPrefix(parseNumericAddress("0.0.0.0"), 0), null /* gateway */)
1098 )
1099
1100 assertTrue(IpReachabilityMonitor.isOnLink(routes, parseNumericAddress("192.168.0.1")))
1101 }
1102
1103 @SuppressLint("NewApi")
1104 @Test
testIsOnLink_withThrowRoutesnull1105 fun testIsOnLink_withThrowRoutes() {
1106 val routes: List<RouteInfo> = listOf(
1107 RouteInfo(
1108 IpPrefix(parseNumericAddress("192.168.0.0"), 16),
1109 null /* gateway */,
1110 null /* iface */,
1111 RouteInfo.RTN_THROW
1112 )
1113 )
1114
1115 assertFalse(IpReachabilityMonitor.isOnLink(routes, parseNumericAddress("192.168.0.1")))
1116 }
1117 }
1118