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_NEVER_REACHABLE_NEIGHBOR_VERSION
63 import com.android.networkstack.util.NetworkStackUtils.IP_REACHABILITY_IGNORE_ORGANIC_NUD_FAILURE_VERSION
64 import com.android.networkstack.util.NetworkStackUtils.IP_REACHABILITY_MCAST_RESOLICIT_VERSION
65 import com.android.networkstack.util.NetworkStackUtils.IP_REACHABILITY_ROUTER_MAC_CHANGE_FAILURE_ONLY_AFTER_ROAM_VERSION
66 import com.android.testutils.makeNewNeighMessage
67 import com.android.testutils.waitForIdle
68 import java.io.FileDescriptor
69 import java.lang.annotation.ElementType
70 import java.lang.annotation.Repeatable
71 import java.lang.annotation.Retention
72 import java.lang.annotation.RetentionPolicy
73 import java.lang.annotation.Target
74 import java.net.Inet4Address
75 import java.net.Inet6Address
76 import java.net.InetAddress
77 import java.util.concurrent.CompletableFuture
78 import java.util.concurrent.ConcurrentLinkedQueue
79 import java.util.concurrent.TimeUnit
80 import kotlin.test.assertFalse
81 import kotlin.test.assertTrue
82 import kotlin.test.fail
83 import org.junit.After
84 import org.junit.Before
85 import org.junit.Rule
86 import org.junit.Test
87 import org.junit.rules.TestName
88 import org.junit.runner.RunWith
89 import org.mockito.ArgumentCaptor
90 import org.mockito.ArgumentMatchers.any
91 import org.mockito.ArgumentMatchers.anyInt
92 import org.mockito.ArgumentMatchers.anyString
93 import org.mockito.ArgumentMatchers.eq
94 import org.mockito.Mockito.doAnswer
95 import org.mockito.Mockito.doReturn
96 import org.mockito.Mockito.mock
97 import org.mockito.Mockito.never
98 import org.mockito.Mockito.timeout
99 import org.mockito.Mockito.verify
100
101 private const val TEST_TIMEOUT_MS = 10_000L
102
103 private val TEST_IPV4_GATEWAY = parseNumericAddress("192.168.222.3") as Inet4Address
104 private val TEST_IPV6_GATEWAY = parseNumericAddress("2001:db8::1") as Inet6Address
105
106 private val TEST_MAC_1 = "001122334455"
107 private val TEST_MAC_2 = "1122334455aa"
108
109 // IPv4 gateway is also DNS server.
110 private val TEST_IPV4_GATEWAY_DNS = parseNumericAddress("192.168.222.100") as Inet4Address
111
112 private val TEST_IPV4_LINKADDR = LinkAddress("192.168.222.123/24")
113 private val TEST_IPV6_LINKADDR = LinkAddress("2001:db8::123/64")
114
115 private val TEST_IPV6_LINKLOCAL_LINKADDR = LinkAddress("fe80::123/64")
116 private val TEST_IPV6_LINKLOCAL_GATEWAY = parseNumericAddress("fe80::1") as Inet6Address
117 private val TEST_IPV6_LINKLOCAL_SCOPED_GATEWAY = parseNumericAddress("fe80::1%21") as Inet6Address
118 private val TEST_IPV6_LINKLOCAL_GATEWAY2 = parseNumericAddress("fe80::2") as Inet6Address
119 private val TEST_IPV6_LINKLOCAL_SCOPED_GATEWAY2 = parseNumericAddress("fe80::2%22") as Inet6Address
120
121 // DNSes inside IP prefix
122 private val TEST_IPV4_DNS = parseNumericAddress("192.168.222.1") as Inet4Address
123 private val TEST_IPV6_DNS = parseNumericAddress("2001:db8::321") as Inet6Address
124 private val TEST_IPV6_DNS2 = parseNumericAddress("2001:db8::456") as Inet6Address
125
126 private val TEST_IFACE = InterfaceParams("fake0", 21, null)
127
128 @SuppressLint("NewApi")
129 private val TEST_LINK_PROPERTIES = LinkProperties().apply {
130 interfaceName = TEST_IFACE.name
131 addLinkAddress(TEST_IPV4_LINKADDR)
132 addLinkAddress(TEST_IPV6_LINKADDR)
133
134 // Add on link routes
135 addRoute(RouteInfo(TEST_IPV4_LINKADDR, null /* gateway */, TEST_IFACE.name))
136 addRoute(RouteInfo(TEST_IPV6_LINKADDR, null /* gateway */, TEST_IFACE.name))
137
138 // Add default routes
139 addRoute(RouteInfo(IpPrefix(parseNumericAddress("0.0.0.0"), 0), TEST_IPV4_GATEWAY))
140 addRoute(RouteInfo(IpPrefix(parseNumericAddress("::"), 0), TEST_IPV6_GATEWAY))
141
142 addDnsServer(TEST_IPV4_DNS)
143 addDnsServer(TEST_IPV6_DNS)
144 }
145
146 @SuppressLint("NewApi")
<lambda>null147 private val TEST_IPV4_ONLY_LINK_PROPERTIES = LinkProperties().apply {
148 interfaceName = TEST_IFACE.name
149 addLinkAddress(TEST_IPV4_LINKADDR)
150
151 // Add on link routes
152 addRoute(RouteInfo(TEST_IPV4_LINKADDR, null /* gateway */, TEST_IFACE.name))
153
154 // Add default routes
155 addRoute(RouteInfo(IpPrefix(parseNumericAddress("0.0.0.0"), 0), TEST_IPV4_GATEWAY_DNS))
156
157 addDnsServer(TEST_IPV4_GATEWAY_DNS)
158 }
159
160 @SuppressLint("NewApi")
<lambda>null161 private val TEST_IPV6_LINKLOCAL_SCOPED_LINK_PROPERTIES = LinkProperties().apply {
162 interfaceName = TEST_IFACE.name
163 addLinkAddress(TEST_IPV6_LINKADDR)
164 addLinkAddress(TEST_IPV6_LINKLOCAL_LINKADDR)
165
166 // Add on link routes
167 addRoute(RouteInfo(TEST_IPV6_LINKADDR, null /* gateway */, TEST_IFACE.name))
168 addRoute(RouteInfo(TEST_IPV6_LINKLOCAL_LINKADDR, null /* gateway */, TEST_IFACE.name))
169
170 // Add default routes
171 addRoute(RouteInfo(IpPrefix(parseNumericAddress("::"), 0), TEST_IPV6_LINKLOCAL_SCOPED_GATEWAY))
172
173 addDnsServer(TEST_IPV6_DNS)
174 }
175
176 @SuppressLint("NewApi")
<lambda>null177 private val TEST_DUAL_LINK_PROPERTIES = LinkProperties().apply {
178 interfaceName = TEST_IFACE.name
179 addLinkAddress(TEST_IPV4_LINKADDR)
180 addLinkAddress(TEST_IPV6_LINKADDR)
181 addLinkAddress(TEST_IPV6_LINKLOCAL_LINKADDR)
182
183 // Add on link routes
184 addRoute(RouteInfo(TEST_IPV4_LINKADDR, null /* gateway */, TEST_IFACE.name))
185 addRoute(RouteInfo(TEST_IPV6_LINKADDR, null /* gateway */, TEST_IFACE.name))
186 addRoute(RouteInfo(TEST_IPV6_LINKLOCAL_LINKADDR, null /* gateway */, TEST_IFACE.name))
187
188 // Add default routes
189 addRoute(RouteInfo(IpPrefix(parseNumericAddress("0.0.0.0"), 0), TEST_IPV4_GATEWAY))
190 addRoute(RouteInfo(IpPrefix(parseNumericAddress("::"), 0), TEST_IPV6_LINKLOCAL_SCOPED_GATEWAY))
191
192 addDnsServer(TEST_IPV4_DNS)
193 addDnsServer(TEST_IPV6_DNS)
194 addDnsServer(TEST_IPV6_DNS2)
195 }
196
197 /**
198 * Tests for IpReachabilityMonitor.
199 */
200 @RunWith(AndroidJUnit4::class)
201 @SmallTest
202 class IpReachabilityMonitorTest {
203 @get:Rule val mTestName = TestName()
204 private val callback = mock(IpReachabilityMonitor.Callback::class.java)
205 private val dependencies = mock(IpReachabilityMonitor.Dependencies::class.java)
206 private val log = mock(SharedLog::class.java)
207 private val context = mock(Context::class.java)
208 private val netd = mock(INetd::class.java)
209 private val fd = mock(FileDescriptor::class.java)
210 private val metricsLog = mock(IpConnectivityLog::class.java)
211 private val mIpReachabilityMonitorMetrics = mock(IpReachabilityMonitorMetrics::class.java)
212
213 private val handlerThread = HandlerThread(IpReachabilityMonitorTest::class.simpleName)
<lambda>null214 private val handler by lazy { Handler(handlerThread.looper) }
215
216 private lateinit var reachabilityMonitor: IpReachabilityMonitor
217 private lateinit var neighborMonitor: TestIpNeighborMonitor
218
219 @Retention(RetentionPolicy.RUNTIME)
220 @Target(ElementType.METHOD)
221 @Repeatable(FlagArray::class)
222 annotation class Flag(val name: String, val enabled: Boolean)
223
224 @Retention(RetentionPolicy.RUNTIME)
225 @Target(ElementType.METHOD)
226 annotation class FlagArray(val value: Array<Flag>)
227
228 /**
229 * A version of [IpNeighborMonitor] that overrides packet reading from a socket, and instead
230 * allows the test to enqueue test packets via [enqueuePacket].
231 */
232 private class TestIpNeighborMonitor(
233 handler: Handler,
234 log: SharedLog,
235 cb: NeighborEventConsumer,
236 private val fd: FileDescriptor
237 ) : IpNeighborMonitor(handler, log, cb) {
238
239 private val pendingPackets = ConcurrentLinkedQueue<ByteArray>()
240 val msgQueue = mock(MessageQueue::class.java)
241
242 private var eventListener: OnFileDescriptorEventListener? = null
243
createFdnull244 override fun createFd() = fd
245 override fun getMessageQueue() = msgQueue
246
247 fun enqueuePacket(packet: ByteArray) {
248 val listener = eventListener ?: fail("IpNeighborMonitor was not yet started")
249 pendingPackets.add(packet)
250 handler.post {
251 listener.onFileDescriptorEvents(fd, OnFileDescriptorEventListener.EVENT_INPUT)
252 }
253 }
254
readPacketnull255 override fun readPacket(fd: FileDescriptor, packetBuffer: ByteArray): Int {
256 val packet = pendingPackets.poll() ?: throw ErrnoException("No pending packet", EAGAIN)
257 if (packet.size > packetBuffer.size) {
258 fail("Buffer (${packetBuffer.size}) is too small for packet (${packet.size})")
259 }
260 System.arraycopy(packet, 0, packetBuffer, 0, packet.size)
261 return packet.size
262 }
263
onStartnull264 override fun onStart() {
265 super.onStart()
266
267 // Find the file descriptor listener that was registered on the instrumented queue
268 val captor = ArgumentCaptor.forClass(OnFileDescriptorEventListener::class.java)
269 verify(msgQueue).addOnFileDescriptorEventListener(
270 eq(fd),
271 anyInt(),
272 captor.capture()
273 )
274 eventListener = captor.value
275 }
276 }
277
278 @Before
setUpnull279 fun setUp() {
280 doReturn(log).`when`(log).forSubComponent(anyString())
281 doReturn(true).`when`(fd).valid()
282 handlerThread.start()
283
284 doAnswer { inv ->
285 val handler = inv.getArgument<Handler>(0)
286 val log = inv.getArgument<SharedLog>(1)
287 val cb = inv.getArgument<IpNeighborMonitor.NeighborEventConsumer>(2)
288 neighborMonitor = TestIpNeighborMonitor(handler, log, cb, fd)
289 neighborMonitor
290 }.`when`(dependencies).makeIpNeighborMonitor(any(), any(), any())
291 doReturn(mIpReachabilityMonitorMetrics)
292 .`when`(dependencies).getIpReachabilityMonitorMetrics()
293
294 // Set flags based on test method annotations.
295 // Note: because dependencies is a mock, all features that are not specified in flag
296 // annotations are either disabled or chickened out.
297 var testMethod = this::class.java.getMethod(mTestName.methodName)
298 val flags = testMethod.getAnnotationsByType(Flag::class.java)
299 for (f in flags) {
300 doReturn(f.enabled).`when`(dependencies).isFeatureEnabled(any(), eq(f.name))
301 doReturn(f.enabled).`when`(dependencies).isFeatureNotChickenedOut(any(), eq(f.name))
302 }
303
304 val monitorFuture = CompletableFuture<IpReachabilityMonitor>()
305 // IpReachabilityMonitor needs to be started from the handler thread
306 handler.post {
307 monitorFuture.complete(IpReachabilityMonitor(
308 context,
309 TEST_IFACE,
310 handler,
311 log,
312 callback,
313 false /* useMultinetworkPolicyTracker */,
314 dependencies,
315 metricsLog,
316 netd))
317 }
318 reachabilityMonitor = monitorFuture.get(TEST_TIMEOUT_MS, TimeUnit.MILLISECONDS)
319 assertTrue(
320 ::neighborMonitor.isInitialized,
321 "IpReachabilityMonitor did not call makeIpNeighborMonitor"
322 )
323 }
324
325 @After
tearDownnull326 fun tearDown() {
327 // Ensure the handler thread is not accessing the fd while changing its mock
328 handlerThread.waitForIdle(TEST_TIMEOUT_MS)
329 doReturn(false).`when`(fd).valid()
330 handlerThread.quitSafely()
331 }
332
333 @Test
testLoseProvisioning_FirstProbeIsFailednull334 fun testLoseProvisioning_FirstProbeIsFailed() {
335 reachabilityMonitor.updateLinkProperties(TEST_LINK_PROPERTIES)
336
337 neighborMonitor.enqueuePacket(makeNewNeighMessage(TEST_IPV4_DNS, NUD_FAILED))
338 verify(callback, timeout(TEST_TIMEOUT_MS)).notifyLost(
339 anyString(),
340 eq(NUD_ORGANIC_FAILED_CRITICAL)
341 )
342 }
343
runLoseProvisioningTestnull344 private fun runLoseProvisioningTest(
345 newLp: LinkProperties,
346 lostNeighbor: InetAddress,
347 eventType: NudEventType
348 ) {
349 runLoseProvisioningTest(
350 newLp,
351 lostNeighbor,
352 eventType,
353 false, /* everReachable */
354 true /* expectedNotifyLost */
355 )
356 }
357
runLoseProvisioningTestnull358 private fun runLoseProvisioningTest(
359 newLp: LinkProperties,
360 lostNeighbor: InetAddress,
361 eventType: NudEventType,
362 everReachable: Boolean,
363 expectedNotifyLost: Boolean
364 ) {
365 reachabilityMonitor.updateLinkProperties(newLp)
366
367 neighborMonitor.enqueuePacket(makeNewNeighMessage(TEST_IPV4_GATEWAY, NUD_STALE))
368 neighborMonitor.enqueuePacket(makeNewNeighMessage(TEST_IPV6_GATEWAY, NUD_STALE))
369 neighborMonitor.enqueuePacket(makeNewNeighMessage(TEST_IPV4_DNS, NUD_STALE))
370 neighborMonitor.enqueuePacket(makeNewNeighMessage(TEST_IPV6_DNS, NUD_STALE))
371 if (everReachable) {
372 neighborMonitor.enqueuePacket(makeNewNeighMessage(TEST_IPV4_DNS, NUD_REACHABLE))
373 neighborMonitor.enqueuePacket(makeNewNeighMessage(TEST_IPV4_GATEWAY, NUD_REACHABLE))
374 neighborMonitor.enqueuePacket(makeNewNeighMessage(TEST_IPV6_DNS, NUD_REACHABLE))
375 neighborMonitor.enqueuePacket(makeNewNeighMessage(TEST_IPV6_GATEWAY, NUD_REACHABLE))
376 }
377
378 neighborMonitor.enqueuePacket(makeNewNeighMessage(lostNeighbor, NUD_PROBE))
379 neighborMonitor.enqueuePacket(makeNewNeighMessage(lostNeighbor, NUD_FAILED))
380 handlerThread.waitForIdle(TEST_TIMEOUT_MS)
381
382 if (expectedNotifyLost) {
383 verify(callback, timeout(TEST_TIMEOUT_MS)).notifyLost(
384 anyString(),
385 eq(eventType)
386 )
387 } else {
388 verify(callback, never()).notifyLost(anyString(), any())
389 }
390 }
391
verifyNudFailureMetricsnull392 private fun verifyNudFailureMetrics(
393 eventType: NudEventType,
394 ipType: IpType,
395 lostNeighborType: NudNeighborType
396 ) {
397 verify(mIpReachabilityMonitorMetrics, timeout(TEST_TIMEOUT_MS)).setNudIpType(eq(ipType))
398 verify(mIpReachabilityMonitorMetrics, timeout(TEST_TIMEOUT_MS))
399 .setNudEventType(eq(eventType))
400 verify(mIpReachabilityMonitorMetrics, timeout(TEST_TIMEOUT_MS))
401 .setNudNeighborType(eq(lostNeighborType))
402 }
403
verifyNudFailureMetricsNotReportednull404 private fun verifyNudFailureMetricsNotReported(
405 ) {
406 verify(mIpReachabilityMonitorMetrics, never()).setNudIpType(any())
407 verify(mIpReachabilityMonitorMetrics, never()).setNudEventType(any())
408 verify(mIpReachabilityMonitorMetrics, never()).setNudNeighborType(any())
409 }
410
411 // Verify if the notifyLost will be called when one neighbor has lost but it's still
412 // provisioned.
runLoseNeighborStillProvisionedTestnull413 private fun runLoseNeighborStillProvisionedTest(
414 newLp: LinkProperties,
415 lostNeighbor: InetAddress,
416 eventType: NudEventType,
417 ipType: IpType,
418 lostNeighborType: NudNeighborType
419 ) {
420 reachabilityMonitor.updateLinkProperties(newLp)
421
422 neighborMonitor.enqueuePacket(makeNewNeighMessage(lostNeighbor, NUD_FAILED))
423 handlerThread.waitForIdle(TEST_TIMEOUT_MS)
424 verify(callback, never()).notifyLost(anyString(), any(NudEventType::class.java))
425 verifyNudFailureMetrics(eventType, ipType, lostNeighborType)
426 }
427
prepareNeighborReachableButMacAddrChangedTestnull428 private fun prepareNeighborReachableButMacAddrChangedTest(
429 newLp: LinkProperties,
430 neighbor: InetAddress,
431 macaddr: String
432 ) {
433 reachabilityMonitor.updateLinkProperties(newLp)
434
435 neighborMonitor.enqueuePacket(makeNewNeighMessage(neighbor, NUD_REACHABLE, macaddr))
436 handlerThread.waitForIdle(TEST_TIMEOUT_MS)
437 verify(callback, never()).notifyLost(
438 anyString(),
439 any(NudEventType::class.java)
440 )
441 }
442
443 @Test
testLoseProvisioning_Ipv4DnsLostnull444 fun testLoseProvisioning_Ipv4DnsLost() {
445 runLoseProvisioningTest(TEST_LINK_PROPERTIES, TEST_IPV4_DNS, NUD_ORGANIC_FAILED_CRITICAL)
446 }
447
448 @Test
testLoseProvisioning_Ipv6DnsLostnull449 fun testLoseProvisioning_Ipv6DnsLost() {
450 runLoseProvisioningTest(TEST_LINK_PROPERTIES, TEST_IPV6_DNS, NUD_ORGANIC_FAILED_CRITICAL)
451 }
452
453 @Test
testLoseProvisioning_Ipv4GatewayLostnull454 fun testLoseProvisioning_Ipv4GatewayLost() {
455 runLoseProvisioningTest(
456 TEST_LINK_PROPERTIES,
457 TEST_IPV4_GATEWAY,
458 NUD_ORGANIC_FAILED_CRITICAL
459 )
460 }
461
462 @Test
testLoseProvisioning_Ipv6GatewayLostnull463 fun testLoseProvisioning_Ipv6GatewayLost() {
464 runLoseProvisioningTest(
465 TEST_LINK_PROPERTIES,
466 TEST_IPV6_GATEWAY,
467 NUD_ORGANIC_FAILED_CRITICAL
468 )
469 }
470
471 @Test
472 @Flag(name = IP_REACHABILITY_IGNORE_ORGANIC_NUD_FAILURE_VERSION, enabled = true)
testLoseProvisioning_ignoreOrganicIpv4DnsLostnull473 fun testLoseProvisioning_ignoreOrganicIpv4DnsLost() {
474 runLoseProvisioningTest(
475 TEST_LINK_PROPERTIES,
476 TEST_IPV4_DNS,
477 NUD_ORGANIC_FAILED_CRITICAL,
478 false /* everReachable */,
479 false /* expectedNotifyLost */
480 )
481 }
482
483 @Test
484 @Flag(name = IP_REACHABILITY_IGNORE_ORGANIC_NUD_FAILURE_VERSION, enabled = true)
testLoseProvisioning_ignoreOrganicIpv6DnsLostnull485 fun testLoseProvisioning_ignoreOrganicIpv6DnsLost() {
486 runLoseProvisioningTest(
487 TEST_LINK_PROPERTIES,
488 TEST_IPV6_DNS,
489 NUD_ORGANIC_FAILED_CRITICAL,
490 false /* everReachable */,
491 false /* expectedNotifyLost */
492 )
493 }
494
495 @Test
496 @Flag(name = IP_REACHABILITY_IGNORE_ORGANIC_NUD_FAILURE_VERSION, enabled = true)
testLoseProvisioning_ignoreOrganicIpv4GatewayLostnull497 fun testLoseProvisioning_ignoreOrganicIpv4GatewayLost() {
498 runLoseProvisioningTest(
499 TEST_LINK_PROPERTIES,
500 TEST_IPV4_GATEWAY,
501 NUD_ORGANIC_FAILED_CRITICAL,
502 false /* everReachable */,
503 false /* expectedNotifyLost */
504 )
505 }
506
507 @Test
508 @Flag(name = IP_REACHABILITY_IGNORE_ORGANIC_NUD_FAILURE_VERSION, enabled = true)
testLoseProvisioning_ignoreOrganicIpv6GatewayLostnull509 fun testLoseProvisioning_ignoreOrganicIpv6GatewayLost() {
510 runLoseProvisioningTest(
511 TEST_LINK_PROPERTIES,
512 TEST_IPV6_GATEWAY,
513 NUD_ORGANIC_FAILED_CRITICAL,
514 false /* everReachable */,
515 false /* expectedNotifyLost */
516 )
517 }
518
519 @Test
520 @Flag(name = IP_REACHABILITY_IGNORE_NEVER_REACHABLE_NEIGHBOR_VERSION, enabled = true)
testLoseProvisioning_ignoreNeverReachableIpv6GatewayLostnull521 fun testLoseProvisioning_ignoreNeverReachableIpv6GatewayLost() {
522 runLoseProvisioningTest(
523 TEST_LINK_PROPERTIES,
524 TEST_IPV6_GATEWAY,
525 NUD_ORGANIC_FAILED_CRITICAL,
526 false /* everReachable */,
527 false /* expectedNotifyLost */
528 )
529 }
530
531 @Test
532 @Flag(name = IP_REACHABILITY_IGNORE_NEVER_REACHABLE_NEIGHBOR_VERSION, enabled = true)
testLoseProvisioning_ignoreNeverReachableIpv6DnsLostnull533 fun testLoseProvisioning_ignoreNeverReachableIpv6DnsLost() {
534 runLoseProvisioningTest(
535 TEST_LINK_PROPERTIES,
536 TEST_IPV6_DNS,
537 NUD_ORGANIC_FAILED_CRITICAL,
538 false /* everReachable */,
539 false /* expectedNotifyLost */
540 )
541 }
542
543 @Test
544 @Flag(name = IP_REACHABILITY_IGNORE_NEVER_REACHABLE_NEIGHBOR_VERSION, enabled = true)
testLoseProvisioning_notIgnoreEverReachableIpv6GatewayLostnull545 fun testLoseProvisioning_notIgnoreEverReachableIpv6GatewayLost() {
546 runLoseProvisioningTest(
547 TEST_LINK_PROPERTIES,
548 TEST_IPV6_GATEWAY,
549 NUD_ORGANIC_FAILED_CRITICAL,
550 true /* everReachable */,
551 true /* expectedNotifyLost */
552 )
553 }
554
555 @Test
556 @Flag(name = IP_REACHABILITY_IGNORE_NEVER_REACHABLE_NEIGHBOR_VERSION, enabled = true)
testLoseProvisioning_notIgnoreEverReachableIpv6DnsLostnull557 fun testLoseProvisioning_notIgnoreEverReachableIpv6DnsLost() {
558 runLoseProvisioningTest(
559 TEST_LINK_PROPERTIES,
560 TEST_IPV6_DNS,
561 NUD_ORGANIC_FAILED_CRITICAL,
562 true /* everReachable */,
563 true /* expectedNotifyLost */
564 )
565 }
566
567 @Test
568 @Flag(name = IP_REACHABILITY_IGNORE_NEVER_REACHABLE_NEIGHBOR_VERSION, enabled = true)
testLoseProvisioning_ignoreNeverReachableIpv4DnsLostnull569 fun testLoseProvisioning_ignoreNeverReachableIpv4DnsLost() {
570 runLoseProvisioningTest(
571 TEST_LINK_PROPERTIES,
572 TEST_IPV4_DNS,
573 NUD_ORGANIC_FAILED_CRITICAL,
574 false /* everReachable */,
575 false /* expectedNotifyLost */
576 )
577 }
578
579 @Test
580 @Flag(name = IP_REACHABILITY_IGNORE_NEVER_REACHABLE_NEIGHBOR_VERSION, enabled = true)
testLoseProvisioning_notIgnoreEverReachableIpv4GatewayLostnull581 fun testLoseProvisioning_notIgnoreEverReachableIpv4GatewayLost() {
582 runLoseProvisioningTest(
583 TEST_LINK_PROPERTIES,
584 TEST_IPV4_GATEWAY,
585 NUD_ORGANIC_FAILED_CRITICAL,
586 true /* everReachable */,
587 true /* expectedNotifyLost */
588 )
589 }
590
591 @Test
592 @Flag(name = IP_REACHABILITY_IGNORE_NEVER_REACHABLE_NEIGHBOR_VERSION, enabled = true)
testLoseProvisioning_notIgnoreEverReachableIpv4DnsLostnull593 fun testLoseProvisioning_notIgnoreEverReachableIpv4DnsLost() {
594 runLoseProvisioningTest(
595 TEST_LINK_PROPERTIES,
596 TEST_IPV4_DNS,
597 NUD_ORGANIC_FAILED_CRITICAL,
598 true /* everReachable */,
599 true /* expectedNotifyLost */
600 )
601 }
602
603 @Test
604 @Flag(name = IP_REACHABILITY_IGNORE_NEVER_REACHABLE_NEIGHBOR_VERSION, enabled = true)
testLoseProvisioning_ignoreNeverReachableIpv6GatewayLost_withTwoIPv6DnsServersnull605 fun testLoseProvisioning_ignoreNeverReachableIpv6GatewayLost_withTwoIPv6DnsServers() {
606 reachabilityMonitor.updateLinkProperties(TEST_DUAL_LINK_PROPERTIES)
607
608 // IPv6 default router is never reachable, but two DNS servers do.
609 neighborMonitor.enqueuePacket(makeNewNeighMessage(TEST_IPV4_DNS, NUD_REACHABLE))
610 neighborMonitor.enqueuePacket(makeNewNeighMessage(TEST_IPV4_GATEWAY, NUD_REACHABLE))
611 neighborMonitor.enqueuePacket(makeNewNeighMessage(TEST_IPV6_DNS, NUD_REACHABLE))
612 neighborMonitor.enqueuePacket(makeNewNeighMessage(TEST_IPV6_DNS2, NUD_REACHABLE))
613
614 // Push a NUD_FAILED event to IPv6 default router, this event should not trigger
615 // onReachabilityFailure callback given it's never reachable.
616 neighborMonitor.enqueuePacket(makeNewNeighMessage(TEST_IPV6_GATEWAY, NUD_PROBE))
617 neighborMonitor.enqueuePacket(makeNewNeighMessage(TEST_IPV6_GATEWAY, NUD_FAILED))
618 handlerThread.waitForIdle(TEST_TIMEOUT_MS)
619
620 verify(callback, never()).notifyLost(anyString(), any())
621
622 // Then another NUD_FAILED from one of DNS servers, this event should not trigger
623 // onReachabilityFailure callback either.
624 neighborMonitor.enqueuePacket(makeNewNeighMessage(TEST_IPV6_DNS, NUD_PROBE))
625 neighborMonitor.enqueuePacket(makeNewNeighMessage(TEST_IPV6_DNS, NUD_FAILED))
626 handlerThread.waitForIdle(TEST_TIMEOUT_MS)
627
628 verify(callback, never()).notifyLost(anyString(), any())
629
630 // Then we lost all IPv6 DNS servers, onReachabilityFailure callback should be triggered.
631 neighborMonitor.enqueuePacket(makeNewNeighMessage(TEST_IPV6_DNS2, NUD_PROBE))
632 neighborMonitor.enqueuePacket(makeNewNeighMessage(TEST_IPV6_DNS2, NUD_FAILED))
633 handlerThread.waitForIdle(TEST_TIMEOUT_MS)
634
635 verify(callback, timeout(TEST_TIMEOUT_MS)).notifyLost(
636 anyString(),
637 eq(NUD_ORGANIC_FAILED_CRITICAL)
638 )
639 }
640
641 @Test
642 @Flag(name = IP_REACHABILITY_IGNORE_NEVER_REACHABLE_NEIGHBOR_VERSION, enabled = true)
testLoseProvisioning_ignoreNeverReachableIpv6DnsLost_withTwoIPv6Routesnull643 fun testLoseProvisioning_ignoreNeverReachableIpv6DnsLost_withTwoIPv6Routes() {
644 val TEST_DUAL_IPV6_ROUTERS_LINK_PROPERTIES = LinkProperties().apply {
645 interfaceName = TEST_IFACE.name
646 addLinkAddress(TEST_IPV4_LINKADDR)
647 addLinkAddress(TEST_IPV6_LINKADDR)
648 addLinkAddress(TEST_IPV6_LINKLOCAL_LINKADDR)
649
650 // Add on link routes
651 addRoute(RouteInfo(TEST_IPV4_LINKADDR, null /* gateway */, TEST_IFACE.name))
652 addRoute(RouteInfo(TEST_IPV6_LINKADDR, null /* gateway */, TEST_IFACE.name))
653 addRoute(RouteInfo(TEST_IPV6_LINKLOCAL_LINKADDR, null /* gateway */, TEST_IFACE.name))
654
655 // Add default routes: one IPv4 default route and two IPv6 default routes.
656 addRoute(RouteInfo(IpPrefix(parseNumericAddress("0.0.0.0"), 0), TEST_IPV4_GATEWAY))
657 addRoute(
658 RouteInfo(
659 IpPrefix(parseNumericAddress("::"), 0),
660 TEST_IPV6_LINKLOCAL_SCOPED_GATEWAY
661 )
662 )
663 addRoute(
664 RouteInfo(
665 IpPrefix(parseNumericAddress("::"), 0),
666 TEST_IPV6_LINKLOCAL_SCOPED_GATEWAY2
667 )
668 )
669
670 addDnsServer(TEST_IPV4_DNS)
671 addDnsServer(TEST_IPV6_DNS)
672 }
673
674 reachabilityMonitor.updateLinkProperties(TEST_DUAL_IPV6_ROUTERS_LINK_PROPERTIES)
675
676 // IPv6 DNS is never reachable, but two default gateways do.
677 neighborMonitor.enqueuePacket(makeNewNeighMessage(TEST_IPV4_DNS, NUD_REACHABLE))
678 neighborMonitor.enqueuePacket(makeNewNeighMessage(TEST_IPV4_GATEWAY, NUD_REACHABLE))
679 neighborMonitor.enqueuePacket(
680 makeNewNeighMessage(TEST_IPV6_LINKLOCAL_GATEWAY, NUD_REACHABLE)
681 )
682 neighborMonitor.enqueuePacket(
683 makeNewNeighMessage(TEST_IPV6_LINKLOCAL_GATEWAY2, NUD_REACHABLE)
684 )
685
686 // Push a NUD_FAILED event to IPv6 DNS server, this event should not trigger
687 // onReachabilityFailure callback given it's never reachable.
688 neighborMonitor.enqueuePacket(makeNewNeighMessage(TEST_IPV6_DNS, NUD_PROBE))
689 neighborMonitor.enqueuePacket(makeNewNeighMessage(TEST_IPV6_DNS, NUD_FAILED))
690 handlerThread.waitForIdle(TEST_TIMEOUT_MS)
691
692 verify(callback, never()).notifyLost(anyString(), any())
693
694 // Then another NUD_FAILED from one of IPv6 gateways, this event should not trigger
695 // onReachabilityFailure callback either.
696 neighborMonitor.enqueuePacket(makeNewNeighMessage(TEST_IPV6_LINKLOCAL_GATEWAY, NUD_PROBE))
697 neighborMonitor.enqueuePacket(makeNewNeighMessage(TEST_IPV6_LINKLOCAL_GATEWAY, NUD_FAILED))
698 handlerThread.waitForIdle(TEST_TIMEOUT_MS)
699
700 verify(callback, never()).notifyLost(anyString(), any())
701
702 // Then we lost all IPv6 gateways, onReachabilityFailure callback should be triggered.
703 neighborMonitor.enqueuePacket(makeNewNeighMessage(TEST_IPV6_LINKLOCAL_GATEWAY2, NUD_PROBE))
704 neighborMonitor.enqueuePacket(makeNewNeighMessage(TEST_IPV6_LINKLOCAL_GATEWAY2, NUD_FAILED))
705 handlerThread.waitForIdle(TEST_TIMEOUT_MS)
706
707 verify(callback, timeout(TEST_TIMEOUT_MS)).notifyLost(
708 anyString(),
709 eq(NUD_ORGANIC_FAILED_CRITICAL)
710 )
711 }
712
runNudProbeFailureMetricsTestnull713 private fun runNudProbeFailureMetricsTest(
714 lp: LinkProperties,
715 lostNeighbor: InetAddress,
716 eventType: NudEventType,
717 ipType: IpType,
718 lostNeighborType: NudNeighborType
719 ) {
720 runLoseProvisioningTest(lp, lostNeighbor, eventType)
721 verifyNudFailureMetrics(eventType, ipType, lostNeighborType)
722 }
723
724 @Test
testNudProbeFailedMetrics_Ipv6GatewayLostPostRoamingnull725 fun testNudProbeFailedMetrics_Ipv6GatewayLostPostRoaming() {
726 reachabilityMonitor.probeAll(true /* dueToRoam */)
727 runNudProbeFailureMetricsTest(
728 TEST_LINK_PROPERTIES,
729 TEST_IPV6_GATEWAY,
730 NUD_POST_ROAMING_FAILED_CRITICAL,
731 IPV6,
732 NUD_NEIGHBOR_GATEWAY
733 )
734 }
735
736 @Test
testNudProbeFailedMetrics_Ipv4GatewayLostPostRoamingnull737 fun testNudProbeFailedMetrics_Ipv4GatewayLostPostRoaming() {
738 reachabilityMonitor.probeAll(true /* dueToRoam */)
739 runNudProbeFailureMetricsTest(
740 TEST_LINK_PROPERTIES,
741 TEST_IPV4_GATEWAY,
742 NUD_POST_ROAMING_FAILED_CRITICAL,
743 IPV4,
744 NUD_NEIGHBOR_GATEWAY
745 )
746 }
747
748 @Test
testNudProbeFailedMetrics_Ipv6DnsLostPostRoamingnull749 fun testNudProbeFailedMetrics_Ipv6DnsLostPostRoaming() {
750 reachabilityMonitor.probeAll(true /* dueToRoam */)
751 runNudProbeFailureMetricsTest(
752 TEST_LINK_PROPERTIES,
753 TEST_IPV6_DNS,
754 NUD_POST_ROAMING_FAILED_CRITICAL,
755 IPV6,
756 NUD_NEIGHBOR_DNS
757 )
758 }
759
760 @Test
testNudProbeFailedMetrics_Ipv4DnsLostPostRoamingnull761 fun testNudProbeFailedMetrics_Ipv4DnsLostPostRoaming() {
762 reachabilityMonitor.probeAll(true /* dueToRoam */)
763 runNudProbeFailureMetricsTest(
764 TEST_LINK_PROPERTIES,
765 TEST_IPV4_DNS,
766 NUD_POST_ROAMING_FAILED_CRITICAL,
767 IPV4,
768 NUD_NEIGHBOR_DNS
769 )
770 }
771
772 @Test
testNudProbeFailedMetrics_IPv4BothGatewayAndDnsLostPostRoamingnull773 fun testNudProbeFailedMetrics_IPv4BothGatewayAndDnsLostPostRoaming() {
774 reachabilityMonitor.probeAll(true /* dueToRoam */)
775 runNudProbeFailureMetricsTest(
776 TEST_IPV4_ONLY_LINK_PROPERTIES,
777 TEST_IPV4_GATEWAY_DNS,
778 NUD_POST_ROAMING_FAILED_CRITICAL,
779 IPV4,
780 NUD_NEIGHBOR_BOTH
781 )
782 }
783
784 @Test
testNudProbeFailedMetrics_IPv6LinklocalScopedGatewayLostPostRoamingnull785 fun testNudProbeFailedMetrics_IPv6LinklocalScopedGatewayLostPostRoaming() {
786 reachabilityMonitor.probeAll(true /* dueToRoam */)
787 runNudProbeFailureMetricsTest(
788 TEST_IPV6_LINKLOCAL_SCOPED_LINK_PROPERTIES,
789 TEST_IPV6_LINKLOCAL_SCOPED_GATEWAY,
790 NUD_POST_ROAMING_FAILED_CRITICAL,
791 IPV6,
792 NUD_NEIGHBOR_GATEWAY
793 )
794 }
795
796 @Test
testNudProbeFailedMetrics_Ipv6GatewayLostAfterConfirmnull797 fun testNudProbeFailedMetrics_Ipv6GatewayLostAfterConfirm() {
798 reachabilityMonitor.probeAll(false /* dueToRoam */)
799 runNudProbeFailureMetricsTest(
800 TEST_LINK_PROPERTIES,
801 TEST_IPV6_GATEWAY,
802 NUD_CONFIRM_FAILED_CRITICAL,
803 IPV6,
804 NUD_NEIGHBOR_GATEWAY
805 )
806 }
807
808 @Test
testNudProbeFailedMetrics_Ipv4GatewayLostAfterConfirmnull809 fun testNudProbeFailedMetrics_Ipv4GatewayLostAfterConfirm() {
810 reachabilityMonitor.probeAll(false /* dueToRoam */)
811 runNudProbeFailureMetricsTest(
812 TEST_LINK_PROPERTIES,
813 TEST_IPV4_GATEWAY,
814 NUD_CONFIRM_FAILED_CRITICAL,
815 IPV4,
816 NUD_NEIGHBOR_GATEWAY
817 )
818 }
819
820 @Test
testNudProbeFailedMetrics_Ipv6DnsLostAfterConfirmnull821 fun testNudProbeFailedMetrics_Ipv6DnsLostAfterConfirm() {
822 reachabilityMonitor.probeAll(false /* dueToRoam */)
823 runNudProbeFailureMetricsTest(
824 TEST_LINK_PROPERTIES,
825 TEST_IPV6_DNS,
826 NUD_CONFIRM_FAILED_CRITICAL,
827 IPV6,
828 NUD_NEIGHBOR_DNS
829 )
830 }
831
832 @Test
testNudProbeFailedMetrics_Ipv4DnsLostAfterConfirmnull833 fun testNudProbeFailedMetrics_Ipv4DnsLostAfterConfirm() {
834 reachabilityMonitor.probeAll(false /* dueToRoam */)
835 runNudProbeFailureMetricsTest(
836 TEST_LINK_PROPERTIES,
837 TEST_IPV4_DNS,
838 NUD_CONFIRM_FAILED_CRITICAL,
839 IPV4,
840 NUD_NEIGHBOR_DNS
841 )
842 }
843
844 @Test
testNudProbeFailedMetrics_IPv4BothGatewayAndDnsLostAfterConfirmnull845 fun testNudProbeFailedMetrics_IPv4BothGatewayAndDnsLostAfterConfirm() {
846 reachabilityMonitor.probeAll(false /* dueToRoam */)
847 runNudProbeFailureMetricsTest(
848 TEST_IPV4_ONLY_LINK_PROPERTIES,
849 TEST_IPV4_GATEWAY_DNS,
850 NUD_CONFIRM_FAILED_CRITICAL,
851 IPV4,
852 NUD_NEIGHBOR_BOTH
853 )
854 }
855
856 @Test
testNudProbeFailedMetrics_IPv6LinklocalScopedGatewayLostAfterConfirmnull857 fun testNudProbeFailedMetrics_IPv6LinklocalScopedGatewayLostAfterConfirm() {
858 reachabilityMonitor.probeAll(false /* dueToRoam */)
859 runNudProbeFailureMetricsTest(
860 TEST_IPV6_LINKLOCAL_SCOPED_LINK_PROPERTIES,
861 TEST_IPV6_LINKLOCAL_SCOPED_GATEWAY,
862 NUD_CONFIRM_FAILED_CRITICAL,
863 IPV6,
864 NUD_NEIGHBOR_GATEWAY
865 )
866 }
867
868 @Test
testNudProbeFailedMetrics_IPv6GatewayLostOrganicnull869 fun testNudProbeFailedMetrics_IPv6GatewayLostOrganic() {
870 runNudProbeFailureMetricsTest(
871 TEST_LINK_PROPERTIES,
872 TEST_IPV6_GATEWAY,
873 NUD_ORGANIC_FAILED_CRITICAL,
874 IPV6,
875 NUD_NEIGHBOR_GATEWAY
876 )
877 }
878
879 @Test
testNudProbeFailedMetrics_IPv4GatewayLostOrganicnull880 fun testNudProbeFailedMetrics_IPv4GatewayLostOrganic() {
881 runNudProbeFailureMetricsTest(
882 TEST_LINK_PROPERTIES,
883 TEST_IPV4_GATEWAY,
884 NUD_ORGANIC_FAILED_CRITICAL,
885 IPV4,
886 NUD_NEIGHBOR_GATEWAY
887 )
888 }
889
890 @Test
testNudProbeFailedMetrics_IPv6DnsLostOrganicnull891 fun testNudProbeFailedMetrics_IPv6DnsLostOrganic() {
892 runNudProbeFailureMetricsTest(
893 TEST_LINK_PROPERTIES,
894 TEST_IPV6_DNS,
895 NUD_ORGANIC_FAILED_CRITICAL,
896 IPV6,
897 NUD_NEIGHBOR_DNS
898 )
899 }
900
901 @Test
testNudProbeFailedMetrics_IPv4DnsLostOrganicnull902 fun testNudProbeFailedMetrics_IPv4DnsLostOrganic() {
903 runNudProbeFailureMetricsTest(
904 TEST_LINK_PROPERTIES,
905 TEST_IPV4_DNS,
906 NUD_ORGANIC_FAILED_CRITICAL,
907 IPV4,
908 NUD_NEIGHBOR_DNS
909 )
910 }
911
912 @Test
testNudProbeFailedMetrics_IPv4BothGatewayAndDnsLostOrganicnull913 fun testNudProbeFailedMetrics_IPv4BothGatewayAndDnsLostOrganic() {
914 runNudProbeFailureMetricsTest(
915 TEST_IPV4_ONLY_LINK_PROPERTIES,
916 TEST_IPV4_GATEWAY_DNS,
917 NUD_ORGANIC_FAILED_CRITICAL,
918 IPV4,
919 NUD_NEIGHBOR_BOTH
920 )
921 }
922
923 @Test
testNudProbeFailedMetrics_IPv6LinklocalScopedGatewayLostOrganicnull924 fun testNudProbeFailedMetrics_IPv6LinklocalScopedGatewayLostOrganic() {
925 runNudProbeFailureMetricsTest(
926 TEST_IPV6_LINKLOCAL_SCOPED_LINK_PROPERTIES,
927 TEST_IPV6_LINKLOCAL_SCOPED_GATEWAY,
928 NUD_ORGANIC_FAILED_CRITICAL,
929 IPV6,
930 NUD_NEIGHBOR_GATEWAY
931 )
932 }
933
934 @Test
testNudProbeFailedMetrics_IPv6OneDnsNeighborLostPostRoamingnull935 fun testNudProbeFailedMetrics_IPv6OneDnsNeighborLostPostRoaming() {
936 reachabilityMonitor.probeAll(true /* dueToRoam */)
937 runLoseNeighborStillProvisionedTest(
938 TEST_DUAL_LINK_PROPERTIES,
939 TEST_IPV6_DNS,
940 NUD_POST_ROAMING_FAILED,
941 IPV6,
942 NUD_NEIGHBOR_DNS
943 )
944 }
945
946 @Test
testNudProbeFailedMetrics_IPv6OneDnsNeighborLostAfterConfirmnull947 fun testNudProbeFailedMetrics_IPv6OneDnsNeighborLostAfterConfirm() {
948 reachabilityMonitor.probeAll(false /* dueToRoam */)
949 runLoseNeighborStillProvisionedTest(
950 TEST_DUAL_LINK_PROPERTIES,
951 TEST_IPV6_DNS,
952 NUD_CONFIRM_FAILED,
953 IPV6,
954 NUD_NEIGHBOR_DNS
955 )
956 }
957
958 @Test
testNudProbeFailedMetrics_IPv6OneDnsNeighborLostOrganicnull959 fun testNudProbeFailedMetrics_IPv6OneDnsNeighborLostOrganic() {
960 runLoseNeighborStillProvisionedTest(
961 TEST_DUAL_LINK_PROPERTIES,
962 TEST_IPV6_DNS,
963 NUD_ORGANIC_FAILED,
964 IPV6,
965 NUD_NEIGHBOR_DNS
966 )
967 }
968
969 @Test
testNudProbeFailedMetrics_multipleProbesFromRoamFirstnull970 fun testNudProbeFailedMetrics_multipleProbesFromRoamFirst() {
971 reachabilityMonitor.probeAll(true /* dueToRoam */)
972 handlerThread.waitForIdle(TEST_TIMEOUT_MS)
973 Thread.sleep(2)
974 reachabilityMonitor.probeAll(false /* dueToRoam */)
975 runLoseProvisioningTest(
976 TEST_LINK_PROPERTIES,
977 TEST_IPV6_GATEWAY,
978 NUD_POST_ROAMING_FAILED_CRITICAL
979 )
980
981 verifyNudFailureMetrics(NUD_POST_ROAMING_FAILED_CRITICAL, IPV6, NUD_NEIGHBOR_GATEWAY)
982 }
983
984 @Test
testNudProbeFailedMetrics_multipleProbesFromConfirmFirstnull985 fun testNudProbeFailedMetrics_multipleProbesFromConfirmFirst() {
986 reachabilityMonitor.probeAll(false /* dueToRoam */)
987 handlerThread.waitForIdle(TEST_TIMEOUT_MS)
988 Thread.sleep(2)
989 reachabilityMonitor.probeAll(true /* dueToRoam */)
990 runLoseProvisioningTest(
991 TEST_LINK_PROPERTIES,
992 TEST_IPV6_GATEWAY,
993 NUD_CONFIRM_FAILED_CRITICAL
994 )
995
996 verifyNudFailureMetrics(NUD_CONFIRM_FAILED_CRITICAL, IPV6, NUD_NEIGHBOR_GATEWAY)
997 }
998
probeWithNeighborEventnull999 private fun probeWithNeighborEvent(dueToRoam: Boolean, neighbor: InetAddress, macaddr: String) {
1000 reachabilityMonitor.probeAll(dueToRoam)
1001 neighborMonitor.enqueuePacket(makeNewNeighMessage(neighbor, NUD_PROBE, macaddr))
1002 }
1003
verifyNudMacAddrChangednull1004 private fun verifyNudMacAddrChanged(
1005 neighbor: InetAddress,
1006 eventType: NudEventType,
1007 ipType: IpType
1008 ) {
1009 neighborMonitor.enqueuePacket(makeNewNeighMessage(neighbor, NUD_REACHABLE, TEST_MAC_2))
1010 verify(callback, timeout(TEST_TIMEOUT_MS)).notifyLost(
1011 anyString(),
1012 eq(eventType)
1013 )
1014 verifyNudFailureMetrics(eventType, ipType, NUD_NEIGHBOR_GATEWAY)
1015 }
1016
verifyNudMacAddrChangeNotReportednull1017 private fun verifyNudMacAddrChangeNotReported(
1018 neighbor: InetAddress,
1019 ) {
1020 neighborMonitor.enqueuePacket(makeNewNeighMessage(neighbor, NUD_REACHABLE, TEST_MAC_2))
1021 verify(callback, never()).notifyLost(anyString(), any())
1022 verifyNudFailureMetricsNotReported()
1023 }
1024
1025 @Test
1026 @Flag(name = IP_REACHABILITY_MCAST_RESOLICIT_VERSION, true)
1027 @Flag(name = IP_REACHABILITY_ROUTER_MAC_CHANGE_FAILURE_ONLY_AFTER_ROAM_VERSION, enabled = true)
testNudProbeFailedMetrics_defaultIPv6GatewayMacAddrChangedAfterRoamingnull1028 fun testNudProbeFailedMetrics_defaultIPv6GatewayMacAddrChangedAfterRoaming() {
1029 prepareNeighborReachableButMacAddrChangedTest(
1030 TEST_LINK_PROPERTIES,
1031 TEST_IPV6_GATEWAY,
1032 TEST_MAC_1
1033 )
1034 probeWithNeighborEvent(true /* dueToRoam */, TEST_IPV6_GATEWAY, TEST_MAC_1)
1035 verifyNudMacAddrChanged(TEST_IPV6_GATEWAY, NUD_POST_ROAMING_MAC_ADDRESS_CHANGED, IPV6)
1036 }
1037
1038 @Test
1039 @Flag(name = IP_REACHABILITY_MCAST_RESOLICIT_VERSION, true)
1040 @Flag(name = IP_REACHABILITY_ROUTER_MAC_CHANGE_FAILURE_ONLY_AFTER_ROAM_VERSION, enabled = true)
testNudProbeFailedMetrics_defaultIPv4GatewayMacAddrChangedAfterRoamingnull1041 fun testNudProbeFailedMetrics_defaultIPv4GatewayMacAddrChangedAfterRoaming() {
1042 prepareNeighborReachableButMacAddrChangedTest(
1043 TEST_LINK_PROPERTIES,
1044 TEST_IPV4_GATEWAY,
1045 TEST_MAC_1
1046 )
1047
1048 probeWithNeighborEvent(true /* dueToRoam */, TEST_IPV4_GATEWAY, TEST_MAC_1)
1049 verifyNudMacAddrChanged(TEST_IPV4_GATEWAY, NUD_POST_ROAMING_MAC_ADDRESS_CHANGED, IPV4)
1050 }
1051
1052 @Test
1053 @Flag(name = IP_REACHABILITY_MCAST_RESOLICIT_VERSION, true)
1054 @Flag(name = IP_REACHABILITY_ROUTER_MAC_CHANGE_FAILURE_ONLY_AFTER_ROAM_VERSION, enabled = true)
testNudProbeFailedMetrics_defaultIPv6GatewayMacAddrChangedAfterConfirmnull1055 fun testNudProbeFailedMetrics_defaultIPv6GatewayMacAddrChangedAfterConfirm() {
1056 prepareNeighborReachableButMacAddrChangedTest(
1057 TEST_LINK_PROPERTIES,
1058 TEST_IPV6_GATEWAY,
1059 TEST_MAC_1
1060 )
1061
1062 reachabilityMonitor.probeAll(false /* dueToRoam */)
1063 verifyNudMacAddrChangeNotReported(TEST_IPV6_GATEWAY)
1064 }
1065
1066 @Test
1067 @Flag(name = IP_REACHABILITY_MCAST_RESOLICIT_VERSION, true)
1068 @Flag(name = IP_REACHABILITY_ROUTER_MAC_CHANGE_FAILURE_ONLY_AFTER_ROAM_VERSION, enabled = true)
testNudProbeFailedMetrics_defaultIPv6GatewayMacAddrChangedAfterOrganicnull1069 fun testNudProbeFailedMetrics_defaultIPv6GatewayMacAddrChangedAfterOrganic() {
1070 prepareNeighborReachableButMacAddrChangedTest(
1071 TEST_LINK_PROPERTIES,
1072 TEST_IPV6_GATEWAY,
1073 TEST_MAC_1
1074 )
1075
1076 verifyNudMacAddrChangeNotReported(TEST_IPV6_GATEWAY)
1077 }
1078
1079 @SuppressLint("NewApi")
1080 @Test
testIsOnLinknull1081 fun testIsOnLink() {
1082 val routes: List<RouteInfo> = listOf(
1083 RouteInfo(
1084 IpPrefix(parseNumericAddress("192.168.0.0"), 16),
1085 null /* gateway */,
1086 null /* iface */,
1087 RouteInfo.RTN_THROW
1088 ),
1089 RouteInfo(IpPrefix(parseNumericAddress("0.0.0.0"), 0), null /* gateway */)
1090 )
1091
1092 assertTrue(IpReachabilityMonitor.isOnLink(routes, parseNumericAddress("192.168.0.1")))
1093 }
1094
1095 @SuppressLint("NewApi")
1096 @Test
testIsOnLink_withThrowRoutesnull1097 fun testIsOnLink_withThrowRoutes() {
1098 val routes: List<RouteInfo> = listOf(
1099 RouteInfo(
1100 IpPrefix(parseNumericAddress("192.168.0.0"), 16),
1101 null /* gateway */,
1102 null /* iface */,
1103 RouteInfo.RTN_THROW
1104 )
1105 )
1106
1107 assertFalse(IpReachabilityMonitor.isOnLink(routes, parseNumericAddress("192.168.0.1")))
1108 }
1109 }
1110