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 package android.net.ip
17
18 import android.annotation.SuppressLint
19 import android.content.Context
20 import android.net.INetd
21 import android.net.InetAddresses.parseNumericAddress
22 import android.net.IpPrefix
23 import android.net.LinkAddress
24 import android.net.LinkProperties
25 import android.net.RouteInfo
26 import android.net.metrics.IpConnectivityLog
27 import com.android.networkstack.util.NetworkStackUtils.IP_REACHABILITY_MCAST_RESOLICIT_VERSION
28 import android.os.Handler
29 import android.os.HandlerThread
30 import android.os.MessageQueue
31 import android.os.MessageQueue.OnFileDescriptorEventListener
32 import android.stats.connectivity.IpType
33 import android.stats.connectivity.IpType.IPV4
34 import android.stats.connectivity.IpType.IPV6
35 import android.stats.connectivity.NudEventType
36 import android.stats.connectivity.NudEventType.NUD_CONFIRM_FAILED
37 import android.stats.connectivity.NudEventType.NUD_CONFIRM_FAILED_CRITICAL
38 import android.stats.connectivity.NudEventType.NUD_CONFIRM_MAC_ADDRESS_CHANGED
39 import android.stats.connectivity.NudEventType.NUD_POST_ROAMING_FAILED
40 import android.stats.connectivity.NudEventType.NUD_POST_ROAMING_FAILED_CRITICAL
41 import android.stats.connectivity.NudEventType.NUD_POST_ROAMING_MAC_ADDRESS_CHANGED
42 import android.stats.connectivity.NudEventType.NUD_ORGANIC_FAILED
43 import android.stats.connectivity.NudEventType.NUD_ORGANIC_FAILED_CRITICAL
44 import android.stats.connectivity.NudEventType.NUD_ORGANIC_MAC_ADDRESS_CHANGED
45 import android.stats.connectivity.NudNeighborType
46 import android.stats.connectivity.NudNeighborType.NUD_NEIGHBOR_BOTH
47 import android.stats.connectivity.NudNeighborType.NUD_NEIGHBOR_DNS
48 import android.stats.connectivity.NudNeighborType.NUD_NEIGHBOR_GATEWAY
49 import android.system.ErrnoException
50 import android.system.OsConstants.EAGAIN
51 import androidx.test.filters.SmallTest
52 import androidx.test.runner.AndroidJUnit4
53 import com.android.networkstack.metrics.IpReachabilityMonitorMetrics
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_REACHABLE
59 import com.android.net.module.util.netlink.StructNdMsg.NUD_STALE
60 import com.android.testutils.makeNewNeighMessage
61 import com.android.testutils.waitForIdle
62 import org.junit.After
63 import org.junit.Before
64 import org.junit.Test
65 import org.junit.runner.RunWith
66 import org.mockito.ArgumentCaptor
67 import org.mockito.ArgumentMatchers.any
68 import org.mockito.ArgumentMatchers.anyBoolean
69 import org.mockito.ArgumentMatchers.anyInt
70 import org.mockito.ArgumentMatchers.anyObject
71 import org.mockito.ArgumentMatchers.anyString
72 import org.mockito.ArgumentMatchers.eq
73 import org.mockito.Mockito.doAnswer
74 import org.mockito.Mockito.doReturn
75 import org.mockito.Mockito.mock
76 import org.mockito.Mockito.never
77 import org.mockito.Mockito.timeout
78 import org.mockito.Mockito.verify
79 import java.io.FileDescriptor
80 import java.net.Inet4Address
81 import java.net.Inet6Address
82 import java.net.InetAddress
83 import java.util.concurrent.CompletableFuture
84 import java.util.concurrent.ConcurrentLinkedQueue
85 import java.util.concurrent.TimeUnit
86 import kotlin.test.assertFalse
87 import kotlin.test.assertTrue
88 import kotlin.test.fail
89
90 private const val TEST_TIMEOUT_MS = 10_000L
91
92 private val TEST_IPV4_GATEWAY = parseNumericAddress("192.168.222.3") as Inet4Address
93 private val TEST_IPV6_GATEWAY = parseNumericAddress("2001:db8::1") as Inet6Address
94
95 // IPv4 gateway is also DNS server.
96 private val TEST_IPV4_GATEWAY_DNS = parseNumericAddress("192.168.222.100") as Inet4Address
97
98 private val TEST_IPV4_LINKADDR = LinkAddress("192.168.222.123/24")
99 private val TEST_IPV6_LINKADDR = LinkAddress("2001:db8::123/64")
100
101 private val TEST_IPV6_LINKLOCAL_LINKADDR = LinkAddress("fe80::123/64")
102 private val TEST_IPV6_LINKLOCAL_GATEWAY = parseNumericAddress("fe80::1") as Inet6Address
103 private val TEST_IPV6_LINKLOCAL_SCOPED_GATEWAY = parseNumericAddress("fe80::1%21") as Inet6Address
104
105 // DNSes inside IP prefix
106 private val TEST_IPV4_DNS = parseNumericAddress("192.168.222.1") as Inet4Address
107 private val TEST_IPV6_DNS = parseNumericAddress("2001:db8::321") as Inet6Address
108 private val TEST_IPV6_DNS2 = parseNumericAddress("2001:db8::456") as Inet6Address
109
110 private val TEST_IFACE = InterfaceParams("fake0", 21, null)
111
112 @SuppressLint("NewApi")
113 private val TEST_LINK_PROPERTIES = LinkProperties().apply {
114 interfaceName = TEST_IFACE.name
115 addLinkAddress(TEST_IPV4_LINKADDR)
116 addLinkAddress(TEST_IPV6_LINKADDR)
117
118 // Add on link routes
119 addRoute(RouteInfo(TEST_IPV4_LINKADDR, null /* gateway */, TEST_IFACE.name))
120 addRoute(RouteInfo(TEST_IPV6_LINKADDR, null /* gateway */, TEST_IFACE.name))
121
122 // Add default routes
123 addRoute(RouteInfo(IpPrefix(parseNumericAddress("0.0.0.0"), 0), TEST_IPV4_GATEWAY))
124 addRoute(RouteInfo(IpPrefix(parseNumericAddress("::"), 0), TEST_IPV6_GATEWAY))
125
126 addDnsServer(TEST_IPV4_DNS)
127 addDnsServer(TEST_IPV6_DNS)
128 }
129
130 @SuppressLint("NewApi")
<lambda>null131 private val TEST_IPV4_ONLY_LINK_PROPERTIES = LinkProperties().apply {
132 interfaceName = TEST_IFACE.name
133 addLinkAddress(TEST_IPV4_LINKADDR)
134
135 // Add on link routes
136 addRoute(RouteInfo(TEST_IPV4_LINKADDR, null /* gateway */, TEST_IFACE.name))
137
138 // Add default routes
139 addRoute(RouteInfo(IpPrefix(parseNumericAddress("0.0.0.0"), 0), TEST_IPV4_GATEWAY_DNS))
140
141 addDnsServer(TEST_IPV4_GATEWAY_DNS)
142 }
143
144 @SuppressLint("NewApi")
<lambda>null145 private val TEST_IPV6_LINKLOCAL_SCOPED_LINK_PROPERTIES = LinkProperties().apply {
146 interfaceName = TEST_IFACE.name
147 addLinkAddress(TEST_IPV6_LINKADDR)
148 addLinkAddress(TEST_IPV6_LINKLOCAL_LINKADDR)
149
150 // Add on link routes
151 addRoute(RouteInfo(TEST_IPV6_LINKADDR, null /* gateway */, TEST_IFACE.name))
152 addRoute(RouteInfo(TEST_IPV6_LINKLOCAL_LINKADDR, null /* gateway */, TEST_IFACE.name))
153
154 // Add default routes
155 addRoute(RouteInfo(IpPrefix(parseNumericAddress("::"), 0), TEST_IPV6_LINKLOCAL_SCOPED_GATEWAY))
156
157 addDnsServer(TEST_IPV6_DNS)
158 }
159
160 @SuppressLint("NewApi")
<lambda>null161 private val TEST_DUAL_LINK_PROPERTIES = LinkProperties().apply {
162 interfaceName = TEST_IFACE.name
163 addLinkAddress(TEST_IPV4_LINKADDR)
164 addLinkAddress(TEST_IPV6_LINKADDR)
165 addLinkAddress(TEST_IPV6_LINKLOCAL_LINKADDR)
166
167 // Add on link routes
168 addRoute(RouteInfo(TEST_IPV4_LINKADDR, null /* gateway */, TEST_IFACE.name))
169 addRoute(RouteInfo(TEST_IPV6_LINKADDR, null /* gateway */, TEST_IFACE.name))
170 addRoute(RouteInfo(TEST_IPV6_LINKLOCAL_LINKADDR, null /* gateway */, TEST_IFACE.name))
171
172 // Add default routes
173 addRoute(RouteInfo(IpPrefix(parseNumericAddress("0.0.0.0"), 0), TEST_IPV4_GATEWAY))
174 addRoute(RouteInfo(IpPrefix(parseNumericAddress("::"), 0), TEST_IPV6_LINKLOCAL_SCOPED_GATEWAY))
175
176 addDnsServer(TEST_IPV4_DNS)
177 addDnsServer(TEST_IPV6_DNS)
178 addDnsServer(TEST_IPV6_DNS2)
179 }
180
181 /**
182 * Tests for IpReachabilityMonitor.
183 */
184 @RunWith(AndroidJUnit4::class)
185 @SmallTest
186 class IpReachabilityMonitorTest {
187 private val callback = mock(IpReachabilityMonitor.Callback::class.java)
188 private val dependencies = mock(IpReachabilityMonitor.Dependencies::class.java)
189 private val log = mock(SharedLog::class.java)
190 private val context = mock(Context::class.java)
191 private val netd = mock(INetd::class.java)
192 private val fd = mock(FileDescriptor::class.java)
193 private val metricsLog = mock(IpConnectivityLog::class.java)
194 private val mIpReachabilityMonitorMetrics = mock(IpReachabilityMonitorMetrics::class.java)
195
196 private val handlerThread = HandlerThread(IpReachabilityMonitorTest::class.simpleName)
<lambda>null197 private val handler by lazy { Handler(handlerThread.looper) }
198
199 private lateinit var reachabilityMonitor: IpReachabilityMonitor
200 private lateinit var neighborMonitor: TestIpNeighborMonitor
201
202 /**
203 * A version of [IpNeighborMonitor] that overrides packet reading from a socket, and instead
204 * allows the test to enqueue test packets via [enqueuePacket].
205 */
206 private class TestIpNeighborMonitor(
207 handler: Handler,
208 log: SharedLog,
209 cb: NeighborEventConsumer,
210 private val fd: FileDescriptor
211 ) : IpNeighborMonitor(handler, log, cb) {
212
213 private val pendingPackets = ConcurrentLinkedQueue<ByteArray>()
214 val msgQueue = mock(MessageQueue::class.java)
215
216 private var eventListener: OnFileDescriptorEventListener? = null
217
createFdnull218 override fun createFd() = fd
219 override fun getMessageQueue() = msgQueue
220
221 fun enqueuePacket(packet: ByteArray) {
222 val listener = eventListener ?: fail("IpNeighborMonitor was not yet started")
223 pendingPackets.add(packet)
224 handler.post {
225 listener.onFileDescriptorEvents(fd, OnFileDescriptorEventListener.EVENT_INPUT)
226 }
227 }
228
readPacketnull229 override fun readPacket(fd: FileDescriptor, packetBuffer: ByteArray): Int {
230 val packet = pendingPackets.poll() ?: throw ErrnoException("No pending packet", EAGAIN)
231 if (packet.size > packetBuffer.size) {
232 fail("Buffer (${packetBuffer.size}) is too small for packet (${packet.size})")
233 }
234 System.arraycopy(packet, 0, packetBuffer, 0, packet.size)
235 return packet.size
236 }
237
onStartnull238 override fun onStart() {
239 super.onStart()
240
241 // Find the file descriptor listener that was registered on the instrumented queue
242 val captor = ArgumentCaptor.forClass(OnFileDescriptorEventListener::class.java)
243 verify(msgQueue).addOnFileDescriptorEventListener(
244 eq(fd), anyInt(), captor.capture())
245 eventListener = captor.value
246 }
247 }
248
249 @Before
setUpnull250 fun setUp() {
251 doReturn(log).`when`(log).forSubComponent(anyString())
252 doReturn(true).`when`(fd).valid()
253 handlerThread.start()
254
255 doAnswer { inv ->
256 val handler = inv.getArgument<Handler>(0)
257 val log = inv.getArgument<SharedLog>(1)
258 val cb = inv.getArgument<IpNeighborMonitor.NeighborEventConsumer>(2)
259 neighborMonitor = TestIpNeighborMonitor(handler, log, cb, fd)
260 neighborMonitor
261 }.`when`(dependencies).makeIpNeighborMonitor(any(), any(), any())
262 doReturn(mIpReachabilityMonitorMetrics)
263 .`when`(dependencies).getIpReachabilityMonitorMetrics()
264 doReturn(true).`when`(dependencies).isFeatureEnabled(anyObject(),
265 eq(IP_REACHABILITY_MCAST_RESOLICIT_VERSION), anyBoolean())
266
267 val monitorFuture = CompletableFuture<IpReachabilityMonitor>()
268 // IpReachabilityMonitor needs to be started from the handler thread
269 handler.post {
270 monitorFuture.complete(IpReachabilityMonitor(
271 context,
272 TEST_IFACE,
273 handler,
274 log,
275 callback,
276 false /* useMultinetworkPolicyTracker */,
277 dependencies,
278 metricsLog,
279 netd))
280 }
281 reachabilityMonitor = monitorFuture.get(TEST_TIMEOUT_MS, TimeUnit.MILLISECONDS)
282 assertTrue(::neighborMonitor.isInitialized,
283 "IpReachabilityMonitor did not call makeIpNeighborMonitor")
284 }
285
286 @After
tearDownnull287 fun tearDown() {
288 // Ensure the handler thread is not accessing the fd while changing its mock
289 handlerThread.waitForIdle(TEST_TIMEOUT_MS)
290 doReturn(false).`when`(fd).valid()
291 handlerThread.quitSafely()
292 }
293
294 @Test
testLoseProvisioning_FirstProbeIsFailednull295 fun testLoseProvisioning_FirstProbeIsFailed() {
296 reachabilityMonitor.updateLinkProperties(TEST_LINK_PROPERTIES)
297
298 neighborMonitor.enqueuePacket(makeNewNeighMessage(TEST_IPV4_DNS, NUD_FAILED))
299 verify(callback, timeout(TEST_TIMEOUT_MS)).notifyLost(eq(TEST_IPV4_DNS), anyString(),
300 eq(NUD_ORGANIC_FAILED_CRITICAL))
301 }
302
runLoseProvisioningTestnull303 private fun runLoseProvisioningTest(
304 newLp: LinkProperties,
305 lostNeighbor: InetAddress,
306 eventType: NudEventType
307 ) {
308 reachabilityMonitor.updateLinkProperties(newLp)
309
310 neighborMonitor.enqueuePacket(makeNewNeighMessage(TEST_IPV4_GATEWAY, NUD_STALE))
311 neighborMonitor.enqueuePacket(makeNewNeighMessage(TEST_IPV6_GATEWAY, NUD_STALE))
312 neighborMonitor.enqueuePacket(makeNewNeighMessage(TEST_IPV4_DNS, NUD_STALE))
313 neighborMonitor.enqueuePacket(makeNewNeighMessage(TEST_IPV6_DNS, NUD_STALE))
314
315 neighborMonitor.enqueuePacket(makeNewNeighMessage(lostNeighbor, NUD_FAILED))
316 verify(callback, timeout(TEST_TIMEOUT_MS)).notifyLost(eq(lostNeighbor), anyString(),
317 eq(eventType))
318 }
319
verifyNudFailureMetricsnull320 private fun verifyNudFailureMetrics(
321 eventType: NudEventType,
322 ipType: IpType,
323 lostNeighborType: NudNeighborType
324 ) {
325 verify(mIpReachabilityMonitorMetrics, timeout(TEST_TIMEOUT_MS)).setNudIpType(eq(ipType))
326 verify(mIpReachabilityMonitorMetrics, timeout(TEST_TIMEOUT_MS))
327 .setNudEventType(eq(eventType))
328 verify(mIpReachabilityMonitorMetrics, timeout(TEST_TIMEOUT_MS))
329 .setNudNeighborType(eq(lostNeighborType))
330 }
331
332 // Verify if the notifyLost will be called when one neighbor has lost but it's still
333 // provisioned.
runLoseNeighborStillProvisionedTestnull334 private fun runLoseNeighborStillProvisionedTest(
335 newLp: LinkProperties,
336 lostNeighbor: InetAddress,
337 eventType: NudEventType,
338 ipType: IpType,
339 lostNeighborType: NudNeighborType
340 ) {
341 reachabilityMonitor.updateLinkProperties(newLp)
342
343 neighborMonitor.enqueuePacket(makeNewNeighMessage(lostNeighbor, NUD_FAILED))
344 handlerThread.waitForIdle(TEST_TIMEOUT_MS)
345 verify(callback, never()).notifyLost(any(), anyString(), any(NudEventType::class.java))
346 verifyNudFailureMetrics(eventType, ipType, lostNeighborType)
347 }
348
prepareNeighborReachableButMacAddrChangedTestnull349 private fun prepareNeighborReachableButMacAddrChangedTest(
350 newLp: LinkProperties,
351 neighbor: InetAddress
352 ) {
353 reachabilityMonitor.updateLinkProperties(newLp)
354
355 neighborMonitor.enqueuePacket(makeNewNeighMessage(neighbor, NUD_REACHABLE,
356 "001122334455" /* oldMac */))
357 handlerThread.waitForIdle(TEST_TIMEOUT_MS)
358 verify(callback, never()).notifyLost(eq(neighbor), anyString(),
359 any(NudEventType::class.java))
360 }
361
362 @Test
testLoseProvisioning_Ipv4DnsLostnull363 fun testLoseProvisioning_Ipv4DnsLost() {
364 runLoseProvisioningTest(TEST_LINK_PROPERTIES, TEST_IPV4_DNS, NUD_ORGANIC_FAILED_CRITICAL)
365 }
366
367 @Test
testLoseProvisioning_Ipv6DnsLostnull368 fun testLoseProvisioning_Ipv6DnsLost() {
369 runLoseProvisioningTest(TEST_LINK_PROPERTIES, TEST_IPV6_DNS, NUD_ORGANIC_FAILED_CRITICAL)
370 }
371
372 @Test
testLoseProvisioning_Ipv4GatewayLostnull373 fun testLoseProvisioning_Ipv4GatewayLost() {
374 runLoseProvisioningTest(TEST_LINK_PROPERTIES, TEST_IPV4_GATEWAY,
375 NUD_ORGANIC_FAILED_CRITICAL)
376 }
377
378 @Test
testLoseProvisioning_Ipv6GatewayLostnull379 fun testLoseProvisioning_Ipv6GatewayLost() {
380 runLoseProvisioningTest(TEST_LINK_PROPERTIES, TEST_IPV6_GATEWAY,
381 NUD_ORGANIC_FAILED_CRITICAL)
382 }
383
runNudProbeFailureMetricsTestnull384 private fun runNudProbeFailureMetricsTest(
385 lp: LinkProperties,
386 lostNeighbor: InetAddress,
387 eventType: NudEventType,
388 ipType: IpType,
389 lostNeighborType: NudNeighborType
390 ) {
391 runLoseProvisioningTest(lp, lostNeighbor, eventType)
392 verifyNudFailureMetrics(eventType, ipType, lostNeighborType)
393 }
394
395 @Test
testNudProbeFailedMetrics_Ipv6GatewayLostPostRoamingnull396 fun testNudProbeFailedMetrics_Ipv6GatewayLostPostRoaming() {
397 reachabilityMonitor.probeAll(true /* dueToRoam */)
398 runNudProbeFailureMetricsTest(TEST_LINK_PROPERTIES, TEST_IPV6_GATEWAY,
399 NUD_POST_ROAMING_FAILED_CRITICAL, IPV6, NUD_NEIGHBOR_GATEWAY)
400 }
401
402 @Test
testNudProbeFailedMetrics_Ipv4GatewayLostPostRoamingnull403 fun testNudProbeFailedMetrics_Ipv4GatewayLostPostRoaming() {
404 reachabilityMonitor.probeAll(true /* dueToRoam */)
405 runNudProbeFailureMetricsTest(TEST_LINK_PROPERTIES, TEST_IPV4_GATEWAY,
406 NUD_POST_ROAMING_FAILED_CRITICAL, IPV4, NUD_NEIGHBOR_GATEWAY)
407 }
408
409 @Test
testNudProbeFailedMetrics_Ipv6DnsLostPostRoamingnull410 fun testNudProbeFailedMetrics_Ipv6DnsLostPostRoaming() {
411 reachabilityMonitor.probeAll(true /* dueToRoam */)
412 runNudProbeFailureMetricsTest(TEST_LINK_PROPERTIES, TEST_IPV6_DNS,
413 NUD_POST_ROAMING_FAILED_CRITICAL, IPV6, NUD_NEIGHBOR_DNS)
414 }
415
416 @Test
testNudProbeFailedMetrics_Ipv4DnsLostPostRoamingnull417 fun testNudProbeFailedMetrics_Ipv4DnsLostPostRoaming() {
418 reachabilityMonitor.probeAll(true /* dueToRoam */)
419 runNudProbeFailureMetricsTest(TEST_LINK_PROPERTIES, TEST_IPV4_DNS,
420 NUD_POST_ROAMING_FAILED_CRITICAL, IPV4, NUD_NEIGHBOR_DNS)
421 }
422
423 @Test
testNudProbeFailedMetrics_IPv4BothGatewayAndDnsLostPostRoamingnull424 fun testNudProbeFailedMetrics_IPv4BothGatewayAndDnsLostPostRoaming() {
425 reachabilityMonitor.probeAll(true /* dueToRoam */)
426 runNudProbeFailureMetricsTest(TEST_IPV4_ONLY_LINK_PROPERTIES, TEST_IPV4_GATEWAY_DNS,
427 NUD_POST_ROAMING_FAILED_CRITICAL, IPV4, NUD_NEIGHBOR_BOTH)
428 }
429
430 @Test
testNudProbeFailedMetrics_IPv6LinklocalScopedGatewayLostPostRoamingnull431 fun testNudProbeFailedMetrics_IPv6LinklocalScopedGatewayLostPostRoaming() {
432 reachabilityMonitor.probeAll(true /* dueToRoam */)
433 runNudProbeFailureMetricsTest(TEST_IPV6_LINKLOCAL_SCOPED_LINK_PROPERTIES,
434 TEST_IPV6_LINKLOCAL_SCOPED_GATEWAY, NUD_POST_ROAMING_FAILED_CRITICAL, IPV6,
435 NUD_NEIGHBOR_GATEWAY)
436 }
437
438 @Test
testNudProbeFailedMetrics_Ipv6GatewayLostAfterConfirmnull439 fun testNudProbeFailedMetrics_Ipv6GatewayLostAfterConfirm() {
440 reachabilityMonitor.probeAll(false /* dueToRoam */)
441 runNudProbeFailureMetricsTest(TEST_LINK_PROPERTIES, TEST_IPV6_GATEWAY,
442 NUD_CONFIRM_FAILED_CRITICAL, IPV6, NUD_NEIGHBOR_GATEWAY)
443 }
444
445 @Test
testNudProbeFailedMetrics_Ipv4GatewayLostAfterConfirmnull446 fun testNudProbeFailedMetrics_Ipv4GatewayLostAfterConfirm() {
447 reachabilityMonitor.probeAll(false /* dueToRoam */)
448 runNudProbeFailureMetricsTest(TEST_LINK_PROPERTIES, TEST_IPV4_GATEWAY,
449 NUD_CONFIRM_FAILED_CRITICAL, IPV4, NUD_NEIGHBOR_GATEWAY)
450 }
451
452 @Test
testNudProbeFailedMetrics_Ipv6DnsLostAfterConfirmnull453 fun testNudProbeFailedMetrics_Ipv6DnsLostAfterConfirm() {
454 reachabilityMonitor.probeAll(false /* dueToRoam */)
455 runNudProbeFailureMetricsTest(TEST_LINK_PROPERTIES, TEST_IPV6_DNS,
456 NUD_CONFIRM_FAILED_CRITICAL, IPV6, NUD_NEIGHBOR_DNS)
457 }
458
459 @Test
testNudProbeFailedMetrics_Ipv4DnsLostAfterConfirmnull460 fun testNudProbeFailedMetrics_Ipv4DnsLostAfterConfirm() {
461 reachabilityMonitor.probeAll(false /* dueToRoam */)
462 runNudProbeFailureMetricsTest(TEST_LINK_PROPERTIES, TEST_IPV4_DNS,
463 NUD_CONFIRM_FAILED_CRITICAL, IPV4, NUD_NEIGHBOR_DNS)
464 }
465
466 @Test
testNudProbeFailedMetrics_IPv4BothGatewayAndDnsLostAfterConfirmnull467 fun testNudProbeFailedMetrics_IPv4BothGatewayAndDnsLostAfterConfirm() {
468 reachabilityMonitor.probeAll(false /* dueToRoam */)
469 runNudProbeFailureMetricsTest(TEST_IPV4_ONLY_LINK_PROPERTIES, TEST_IPV4_GATEWAY_DNS,
470 NUD_CONFIRM_FAILED_CRITICAL, IPV4, NUD_NEIGHBOR_BOTH)
471 }
472
473 @Test
testNudProbeFailedMetrics_IPv6LinklocalScopedGatewayLostAfterConfirmnull474 fun testNudProbeFailedMetrics_IPv6LinklocalScopedGatewayLostAfterConfirm() {
475 reachabilityMonitor.probeAll(false /* dueToRoam */)
476 runNudProbeFailureMetricsTest(TEST_IPV6_LINKLOCAL_SCOPED_LINK_PROPERTIES,
477 TEST_IPV6_LINKLOCAL_SCOPED_GATEWAY, NUD_CONFIRM_FAILED_CRITICAL, IPV6,
478 NUD_NEIGHBOR_GATEWAY)
479 }
480
481 @Test
testNudProbeFailedMetrics_IPv6GatewayLostOrganicnull482 fun testNudProbeFailedMetrics_IPv6GatewayLostOrganic() {
483 runNudProbeFailureMetricsTest(TEST_LINK_PROPERTIES, TEST_IPV6_GATEWAY,
484 NUD_ORGANIC_FAILED_CRITICAL, IPV6, NUD_NEIGHBOR_GATEWAY)
485 }
486
487 @Test
testNudProbeFailedMetrics_IPv4GatewayLostOrganicnull488 fun testNudProbeFailedMetrics_IPv4GatewayLostOrganic() {
489 runNudProbeFailureMetricsTest(TEST_LINK_PROPERTIES, TEST_IPV4_GATEWAY,
490 NUD_ORGANIC_FAILED_CRITICAL, IPV4, NUD_NEIGHBOR_GATEWAY)
491 }
492
493 @Test
testNudProbeFailedMetrics_IPv6DnsLostOrganicnull494 fun testNudProbeFailedMetrics_IPv6DnsLostOrganic() {
495 runNudProbeFailureMetricsTest(TEST_LINK_PROPERTIES, TEST_IPV6_DNS,
496 NUD_ORGANIC_FAILED_CRITICAL, IPV6, NUD_NEIGHBOR_DNS)
497 }
498
499 @Test
testNudProbeFailedMetrics_IPv4DnsLostOrganicnull500 fun testNudProbeFailedMetrics_IPv4DnsLostOrganic() {
501 runNudProbeFailureMetricsTest(TEST_LINK_PROPERTIES, TEST_IPV4_DNS,
502 NUD_ORGANIC_FAILED_CRITICAL, IPV4, NUD_NEIGHBOR_DNS)
503 }
504
505 @Test
testNudProbeFailedMetrics_IPv4BothGatewayAndDnsLostOrganicnull506 fun testNudProbeFailedMetrics_IPv4BothGatewayAndDnsLostOrganic() {
507 runNudProbeFailureMetricsTest(TEST_IPV4_ONLY_LINK_PROPERTIES, TEST_IPV4_GATEWAY_DNS,
508 NUD_ORGANIC_FAILED_CRITICAL, IPV4, NUD_NEIGHBOR_BOTH)
509 }
510
511 @Test
testNudProbeFailedMetrics_IPv6LinklocalScopedGatewayLostOrganicnull512 fun testNudProbeFailedMetrics_IPv6LinklocalScopedGatewayLostOrganic() {
513 runNudProbeFailureMetricsTest(TEST_IPV6_LINKLOCAL_SCOPED_LINK_PROPERTIES,
514 TEST_IPV6_LINKLOCAL_SCOPED_GATEWAY, NUD_ORGANIC_FAILED_CRITICAL, IPV6,
515 NUD_NEIGHBOR_GATEWAY)
516 }
517
518 @Test
testNudProbeFailedMetrics_IPv6OneDnsNeighborLostPostRoamingnull519 fun testNudProbeFailedMetrics_IPv6OneDnsNeighborLostPostRoaming() {
520 reachabilityMonitor.probeAll(true /* dueToRoam */)
521 runLoseNeighborStillProvisionedTest(TEST_DUAL_LINK_PROPERTIES, TEST_IPV6_DNS,
522 NUD_POST_ROAMING_FAILED, IPV6, NUD_NEIGHBOR_DNS)
523 }
524
525 @Test
testNudProbeFailedMetrics_IPv6OneDnsNeighborLostAfterConfirmnull526 fun testNudProbeFailedMetrics_IPv6OneDnsNeighborLostAfterConfirm() {
527 reachabilityMonitor.probeAll(false /* dueToRoam */)
528 runLoseNeighborStillProvisionedTest(TEST_DUAL_LINK_PROPERTIES, TEST_IPV6_DNS,
529 NUD_CONFIRM_FAILED, IPV6, NUD_NEIGHBOR_DNS)
530 }
531
532 @Test
testNudProbeFailedMetrics_IPv6OneDnsNeighborLostOrganicnull533 fun testNudProbeFailedMetrics_IPv6OneDnsNeighborLostOrganic() {
534 runLoseNeighborStillProvisionedTest(TEST_DUAL_LINK_PROPERTIES, TEST_IPV6_DNS,
535 NUD_ORGANIC_FAILED, IPV6, NUD_NEIGHBOR_DNS)
536 }
537
538 @Test
testNudProbeFailedMetrics_multipleProbesFromRoamFirstnull539 fun testNudProbeFailedMetrics_multipleProbesFromRoamFirst() {
540 reachabilityMonitor.probeAll(true /* dueToRoam */)
541 handlerThread.waitForIdle(TEST_TIMEOUT_MS)
542 Thread.sleep(2)
543 reachabilityMonitor.probeAll(false /* dueToRoam */)
544 runLoseProvisioningTest(TEST_LINK_PROPERTIES, TEST_IPV6_GATEWAY,
545 NUD_POST_ROAMING_FAILED_CRITICAL)
546
547 verifyNudFailureMetrics(NUD_POST_ROAMING_FAILED_CRITICAL, IPV6, NUD_NEIGHBOR_GATEWAY)
548 }
549
550 @Test
testNudProbeFailedMetrics_multipleProbesFromConfirmFirstnull551 fun testNudProbeFailedMetrics_multipleProbesFromConfirmFirst() {
552 reachabilityMonitor.probeAll(false /* dueToRoam */)
553 handlerThread.waitForIdle(TEST_TIMEOUT_MS)
554 Thread.sleep(2)
555 reachabilityMonitor.probeAll(true /* dueToRoam */)
556 runLoseProvisioningTest(TEST_LINK_PROPERTIES, TEST_IPV6_GATEWAY,
557 NUD_CONFIRM_FAILED_CRITICAL)
558
559 verifyNudFailureMetrics(NUD_CONFIRM_FAILED_CRITICAL, IPV6, NUD_NEIGHBOR_GATEWAY)
560 }
561
verifyNudMacAddrChangedTypenull562 private fun verifyNudMacAddrChangedType(
563 neighbor: InetAddress,
564 eventType: NudEventType,
565 ipType: IpType
566 ) {
567 neighborMonitor.enqueuePacket(makeNewNeighMessage(neighbor, NUD_REACHABLE,
568 "1122334455aa" /* newMac */))
569 verify(callback, timeout(TEST_TIMEOUT_MS)).notifyLost(eq(neighbor), anyString(),
570 eq(eventType))
571 verifyNudFailureMetrics(eventType, ipType, NUD_NEIGHBOR_GATEWAY)
572 }
573
574 @Test
testNudProbeFailedMetrics_defaultIPv6GatewayMacAddrChangedAfterRoamingnull575 fun testNudProbeFailedMetrics_defaultIPv6GatewayMacAddrChangedAfterRoaming() {
576 prepareNeighborReachableButMacAddrChangedTest(TEST_LINK_PROPERTIES, TEST_IPV6_GATEWAY)
577
578 reachabilityMonitor.probeAll(true /* dueToRoam */)
579 verifyNudMacAddrChangedType(TEST_IPV6_GATEWAY, NUD_POST_ROAMING_MAC_ADDRESS_CHANGED, IPV6)
580 }
581
582 @Test
testNudProbeFailedMetrics_defaultIPv4GatewayMacAddrChangedAfterRoamingnull583 fun testNudProbeFailedMetrics_defaultIPv4GatewayMacAddrChangedAfterRoaming() {
584 prepareNeighborReachableButMacAddrChangedTest(TEST_LINK_PROPERTIES, TEST_IPV4_GATEWAY)
585
586 reachabilityMonitor.probeAll(true /* dueToRoam */)
587 verifyNudMacAddrChangedType(TEST_IPV4_GATEWAY, NUD_POST_ROAMING_MAC_ADDRESS_CHANGED, IPV4)
588 }
589
590 @Test
testNudProbeFailedMetrics_defaultIPv6GatewayMacAddrChangedAfterConfirmnull591 fun testNudProbeFailedMetrics_defaultIPv6GatewayMacAddrChangedAfterConfirm() {
592 prepareNeighborReachableButMacAddrChangedTest(TEST_LINK_PROPERTIES, TEST_IPV6_GATEWAY)
593
594 reachabilityMonitor.probeAll(false /* dueToRoam */)
595 verifyNudMacAddrChangedType(TEST_IPV6_GATEWAY, NUD_CONFIRM_MAC_ADDRESS_CHANGED, IPV6)
596 }
597
598 @Test
testNudProbeFailedMetrics_defaultIPv6GatewayMacAddrChangedAfterOrganicnull599 fun testNudProbeFailedMetrics_defaultIPv6GatewayMacAddrChangedAfterOrganic() {
600 prepareNeighborReachableButMacAddrChangedTest(TEST_LINK_PROPERTIES, TEST_IPV6_GATEWAY)
601
602 verifyNudMacAddrChangedType(TEST_IPV6_GATEWAY, NUD_ORGANIC_MAC_ADDRESS_CHANGED, IPV6)
603 }
604
605 @SuppressLint("NewApi")
606 @Test
testIsOnLinknull607 fun testIsOnLink() {
608 val routes: List<RouteInfo> = listOf(
609 RouteInfo(
610 IpPrefix(parseNumericAddress("192.168.0.0"), 16),
611 null /* gateway */,
612 null /* iface */,
613 RouteInfo.RTN_THROW),
614 RouteInfo(IpPrefix(parseNumericAddress("0.0.0.0"), 0), null /* gateway */)
615 )
616
617 assertTrue(IpReachabilityMonitor.isOnLink(routes, parseNumericAddress("192.168.0.1")))
618 }
619
620 @SuppressLint("NewApi")
621 @Test
testIsOnLink_withThrowRoutesnull622 fun testIsOnLink_withThrowRoutes() {
623 val routes: List<RouteInfo> = listOf(
624 RouteInfo(
625 IpPrefix(parseNumericAddress("192.168.0.0"), 16),
626 null /* gateway */,
627 null /* iface */,
628 RouteInfo.RTN_THROW)
629 )
630
631 assertFalse(IpReachabilityMonitor.isOnLink(routes, parseNumericAddress("192.168.0.1")))
632 }
633 }
634