1 /* 2 * Copyright (C) 2013 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 17 package android.net; 18 19 import static android.system.OsConstants.IFA_F_DADFAILED; 20 import static android.system.OsConstants.IFA_F_DEPRECATED; 21 import static android.system.OsConstants.IFA_F_OPTIMISTIC; 22 import static android.system.OsConstants.IFA_F_PERMANENT; 23 import static android.system.OsConstants.IFA_F_TEMPORARY; 24 import static android.system.OsConstants.IFA_F_TENTATIVE; 25 import static android.system.OsConstants.RT_SCOPE_HOST; 26 import static android.system.OsConstants.RT_SCOPE_LINK; 27 import static android.system.OsConstants.RT_SCOPE_SITE; 28 import static android.system.OsConstants.RT_SCOPE_UNIVERSE; 29 30 import static com.android.testutils.MiscAssertsKt.assertEqualBothWays; 31 import static com.android.testutils.MiscAssertsKt.assertFieldCountEquals; 32 import static com.android.testutils.MiscAssertsKt.assertNotEqualEitherWay; 33 import static com.android.testutils.ParcelUtilsKt.assertParcelingIsLossless; 34 35 import static org.junit.Assert.assertEquals; 36 import static org.junit.Assert.assertFalse; 37 import static org.junit.Assert.assertNotEquals; 38 import static org.junit.Assert.assertTrue; 39 import static org.junit.Assert.fail; 40 41 import android.os.Build; 42 import android.os.SystemClock; 43 44 import androidx.test.filters.SmallTest; 45 import androidx.test.runner.AndroidJUnit4; 46 47 import com.android.testutils.DevSdkIgnoreRule; 48 import com.android.testutils.DevSdkIgnoreRule.IgnoreAfter; 49 import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo; 50 51 import org.junit.Rule; 52 import org.junit.Test; 53 import org.junit.runner.RunWith; 54 55 import java.net.Inet4Address; 56 import java.net.InetAddress; 57 import java.net.InterfaceAddress; 58 import java.net.NetworkInterface; 59 import java.net.SocketException; 60 import java.util.Arrays; 61 import java.util.List; 62 63 @RunWith(AndroidJUnit4.class) 64 @SmallTest 65 public class LinkAddressTest { 66 @Rule 67 public final DevSdkIgnoreRule ignoreRule = new DevSdkIgnoreRule(); 68 69 private static final String V4 = "192.0.2.1"; 70 private static final String V6 = "2001:db8::1"; 71 private static final InetAddress V4_ADDRESS = NetworkUtils.numericToInetAddress(V4); 72 private static final InetAddress V6_ADDRESS = NetworkUtils.numericToInetAddress(V6); 73 74 @Test testConstants()75 public void testConstants() { 76 // RT_SCOPE_UNIVERSE = 0, but all the other constants should be nonzero. 77 assertNotEquals(0, RT_SCOPE_HOST); 78 assertNotEquals(0, RT_SCOPE_LINK); 79 assertNotEquals(0, RT_SCOPE_SITE); 80 81 assertNotEquals(0, IFA_F_DEPRECATED); 82 assertNotEquals(0, IFA_F_PERMANENT); 83 assertNotEquals(0, IFA_F_TENTATIVE); 84 } 85 86 @Test testConstructors()87 public void testConstructors() throws SocketException { 88 LinkAddress address; 89 90 // Valid addresses work as expected. 91 address = new LinkAddress(V4_ADDRESS, 25); 92 assertEquals(V4_ADDRESS, address.getAddress()); 93 assertEquals(25, address.getPrefixLength()); 94 assertEquals(0, address.getFlags()); 95 assertEquals(RT_SCOPE_UNIVERSE, address.getScope()); 96 assertTrue(address.isIpv4()); 97 98 address = new LinkAddress(V6_ADDRESS, 127); 99 assertEquals(V6_ADDRESS, address.getAddress()); 100 assertEquals(127, address.getPrefixLength()); 101 assertEquals(0, address.getFlags()); 102 assertEquals(RT_SCOPE_UNIVERSE, address.getScope()); 103 assertTrue(address.isIpv6()); 104 105 // Nonsensical flags/scopes or combinations thereof are acceptable. 106 address = new LinkAddress(V6 + "/64", IFA_F_DEPRECATED | IFA_F_PERMANENT, RT_SCOPE_LINK); 107 assertEquals(V6_ADDRESS, address.getAddress()); 108 assertEquals(64, address.getPrefixLength()); 109 assertEquals(IFA_F_DEPRECATED | IFA_F_PERMANENT, address.getFlags()); 110 assertEquals(RT_SCOPE_LINK, address.getScope()); 111 assertTrue(address.isIpv6()); 112 113 address = new LinkAddress(V4 + "/23", 123, 456); 114 assertEquals(V4_ADDRESS, address.getAddress()); 115 assertEquals(23, address.getPrefixLength()); 116 assertEquals(123, address.getFlags()); 117 assertEquals(456, address.getScope()); 118 assertTrue(address.isIpv4()); 119 120 // InterfaceAddress doesn't have a constructor. Fetch some from an interface. 121 List<InterfaceAddress> addrs = NetworkInterface.getByName("lo").getInterfaceAddresses(); 122 123 // We expect to find 127.0.0.1/8 and ::1/128, in any order. 124 LinkAddress ipv4Loopback, ipv6Loopback; 125 assertEquals(2, addrs.size()); 126 if (addrs.get(0).getAddress() instanceof Inet4Address) { 127 ipv4Loopback = new LinkAddress(addrs.get(0)); 128 ipv6Loopback = new LinkAddress(addrs.get(1)); 129 } else { 130 ipv4Loopback = new LinkAddress(addrs.get(1)); 131 ipv6Loopback = new LinkAddress(addrs.get(0)); 132 } 133 134 assertEquals(NetworkUtils.numericToInetAddress("127.0.0.1"), ipv4Loopback.getAddress()); 135 assertEquals(8, ipv4Loopback.getPrefixLength()); 136 137 assertEquals(NetworkUtils.numericToInetAddress("::1"), ipv6Loopback.getAddress()); 138 assertEquals(128, ipv6Loopback.getPrefixLength()); 139 140 // Null addresses are rejected. 141 try { 142 address = new LinkAddress(null, 24); 143 fail("Null InetAddress should cause IllegalArgumentException"); 144 } catch(IllegalArgumentException expected) {} 145 146 try { 147 address = new LinkAddress((String) null, IFA_F_PERMANENT, RT_SCOPE_UNIVERSE); 148 fail("Null string should cause IllegalArgumentException"); 149 } catch(IllegalArgumentException expected) {} 150 151 try { 152 address = new LinkAddress((InterfaceAddress) null); 153 fail("Null string should cause NullPointerException"); 154 } catch(NullPointerException expected) {} 155 156 // Invalid prefix lengths are rejected. 157 try { 158 address = new LinkAddress(V4_ADDRESS, -1); 159 fail("Negative IPv4 prefix length should cause IllegalArgumentException"); 160 } catch(IllegalArgumentException expected) {} 161 162 try { 163 address = new LinkAddress(V6_ADDRESS, -1); 164 fail("Negative IPv6 prefix length should cause IllegalArgumentException"); 165 } catch(IllegalArgumentException expected) {} 166 167 try { 168 address = new LinkAddress(V4_ADDRESS, 33); 169 fail("/33 IPv4 prefix length should cause IllegalArgumentException"); 170 } catch(IllegalArgumentException expected) {} 171 172 try { 173 address = new LinkAddress(V4 + "/33", IFA_F_PERMANENT, RT_SCOPE_UNIVERSE); 174 fail("/33 IPv4 prefix length should cause IllegalArgumentException"); 175 } catch(IllegalArgumentException expected) {} 176 177 178 try { 179 address = new LinkAddress(V6_ADDRESS, 129, IFA_F_PERMANENT, RT_SCOPE_UNIVERSE); 180 fail("/129 IPv6 prefix length should cause IllegalArgumentException"); 181 } catch(IllegalArgumentException expected) {} 182 183 try { 184 address = new LinkAddress(V6 + "/129", IFA_F_PERMANENT, RT_SCOPE_UNIVERSE); 185 fail("/129 IPv6 prefix length should cause IllegalArgumentException"); 186 } catch(IllegalArgumentException expected) {} 187 188 // Multicast addresses are rejected. 189 try { 190 address = new LinkAddress("224.0.0.2/32"); 191 fail("IPv4 multicast address should cause IllegalArgumentException"); 192 } catch(IllegalArgumentException expected) {} 193 194 try { 195 address = new LinkAddress("ff02::1/128"); 196 fail("IPv6 multicast address should cause IllegalArgumentException"); 197 } catch(IllegalArgumentException expected) {} 198 } 199 200 @Test testAddressScopes()201 public void testAddressScopes() { 202 assertEquals(RT_SCOPE_HOST, new LinkAddress("::/128").getScope()); 203 assertEquals(RT_SCOPE_HOST, new LinkAddress("0.0.0.0/32").getScope()); 204 205 assertEquals(RT_SCOPE_LINK, new LinkAddress("::1/128").getScope()); 206 assertEquals(RT_SCOPE_LINK, new LinkAddress("127.0.0.5/8").getScope()); 207 assertEquals(RT_SCOPE_LINK, new LinkAddress("fe80::ace:d00d/64").getScope()); 208 assertEquals(RT_SCOPE_LINK, new LinkAddress("169.254.5.12/16").getScope()); 209 210 assertEquals(RT_SCOPE_SITE, new LinkAddress("fec0::dead/64").getScope()); 211 212 assertEquals(RT_SCOPE_UNIVERSE, new LinkAddress("10.1.2.3/21").getScope()); 213 assertEquals(RT_SCOPE_UNIVERSE, new LinkAddress("192.0.2.1/25").getScope()); 214 assertEquals(RT_SCOPE_UNIVERSE, new LinkAddress("2001:db8::/64").getScope()); 215 assertEquals(RT_SCOPE_UNIVERSE, new LinkAddress("5000::/127").getScope()); 216 } 217 assertIsSameAddressAs(LinkAddress l1, LinkAddress l2)218 private void assertIsSameAddressAs(LinkAddress l1, LinkAddress l2) { 219 assertTrue(l1 + " unexpectedly does not have same address as " + l2, 220 l1.isSameAddressAs(l2)); 221 assertTrue(l2 + " unexpectedly does not have same address as " + l1, 222 l2.isSameAddressAs(l1)); 223 } 224 assertIsNotSameAddressAs(LinkAddress l1, LinkAddress l2)225 private void assertIsNotSameAddressAs(LinkAddress l1, LinkAddress l2) { 226 assertFalse(l1 + " unexpectedly has same address as " + l2, 227 l1.isSameAddressAs(l2)); 228 assertFalse(l2 + " unexpectedly has same address as " + l1, 229 l1.isSameAddressAs(l2)); 230 } 231 232 @Test testEqualsAndSameAddressAs()233 public void testEqualsAndSameAddressAs() { 234 LinkAddress l1, l2, l3; 235 236 l1 = new LinkAddress("2001:db8::1/64"); 237 l2 = new LinkAddress("2001:db8::1/64"); 238 assertEqualBothWays(l1, l2); 239 assertIsSameAddressAs(l1, l2); 240 241 l2 = new LinkAddress("2001:db8::1/65"); 242 assertNotEqualEitherWay(l1, l2); 243 assertIsNotSameAddressAs(l1, l2); 244 245 l2 = new LinkAddress("2001:db8::2/64"); 246 assertNotEqualEitherWay(l1, l2); 247 assertIsNotSameAddressAs(l1, l2); 248 249 250 l1 = new LinkAddress("192.0.2.1/24"); 251 l2 = new LinkAddress("192.0.2.1/24"); 252 assertEqualBothWays(l1, l2); 253 assertIsSameAddressAs(l1, l2); 254 255 l2 = new LinkAddress("192.0.2.1/23"); 256 assertNotEqualEitherWay(l1, l2); 257 assertIsNotSameAddressAs(l1, l2); 258 259 l2 = new LinkAddress("192.0.2.2/24"); 260 assertNotEqualEitherWay(l1, l2); 261 assertIsNotSameAddressAs(l1, l2); 262 263 264 // Check equals() and isSameAddressAs() on identical addresses with different flags. 265 l1 = new LinkAddress(V6_ADDRESS, 64); 266 l2 = new LinkAddress(V6_ADDRESS, 64, 0, RT_SCOPE_UNIVERSE); 267 assertEqualBothWays(l1, l2); 268 assertIsSameAddressAs(l1, l2); 269 270 l2 = new LinkAddress(V6_ADDRESS, 64, IFA_F_DEPRECATED, RT_SCOPE_UNIVERSE); 271 assertNotEqualEitherWay(l1, l2); 272 assertIsSameAddressAs(l1, l2); 273 274 // Check equals() and isSameAddressAs() on identical addresses with different scope. 275 l1 = new LinkAddress(V4_ADDRESS, 24); 276 l2 = new LinkAddress(V4_ADDRESS, 24, 0, RT_SCOPE_UNIVERSE); 277 assertEqualBothWays(l1, l2); 278 assertIsSameAddressAs(l1, l2); 279 280 l2 = new LinkAddress(V4_ADDRESS, 24, 0, RT_SCOPE_HOST); 281 assertNotEqualEitherWay(l1, l2); 282 assertIsSameAddressAs(l1, l2); 283 284 // Addresses with the same start or end bytes aren't equal between families. 285 l1 = new LinkAddress("32.1.13.184/24"); 286 l2 = new LinkAddress("2001:db8::1/24"); 287 l3 = new LinkAddress("::2001:db8/24"); 288 289 byte[] ipv4Bytes = l1.getAddress().getAddress(); 290 byte[] l2FirstIPv6Bytes = Arrays.copyOf(l2.getAddress().getAddress(), 4); 291 byte[] l3LastIPv6Bytes = Arrays.copyOfRange(l3.getAddress().getAddress(), 12, 16); 292 assertTrue(Arrays.equals(ipv4Bytes, l2FirstIPv6Bytes)); 293 assertTrue(Arrays.equals(ipv4Bytes, l3LastIPv6Bytes)); 294 295 assertNotEqualEitherWay(l1, l2); 296 assertIsNotSameAddressAs(l1, l2); 297 298 assertNotEqualEitherWay(l1, l3); 299 assertIsNotSameAddressAs(l1, l3); 300 301 // Because we use InetAddress, an IPv4 address is equal to its IPv4-mapped address. 302 // TODO: Investigate fixing this. 303 String addressString = V4 + "/24"; 304 l1 = new LinkAddress(addressString); 305 l2 = new LinkAddress("::ffff:" + addressString); 306 assertEqualBothWays(l1, l2); 307 assertIsSameAddressAs(l1, l2); 308 } 309 310 @Test testHashCode()311 public void testHashCode() { 312 LinkAddress l1, l2; 313 314 l1 = new LinkAddress(V4_ADDRESS, 23); 315 l2 = new LinkAddress(V4_ADDRESS, 23, 0, RT_SCOPE_HOST); 316 assertNotEquals(l1.hashCode(), l2.hashCode()); 317 318 l1 = new LinkAddress(V6_ADDRESS, 128); 319 l2 = new LinkAddress(V6_ADDRESS, 128, IFA_F_TENTATIVE, RT_SCOPE_UNIVERSE); 320 assertNotEquals(l1.hashCode(), l2.hashCode()); 321 } 322 323 @Test testParceling()324 public void testParceling() { 325 LinkAddress l; 326 327 l = new LinkAddress(V6_ADDRESS, 64, 123, 456); 328 assertParcelingIsLossless(l); 329 330 l = new LinkAddress(V4 + "/28", IFA_F_PERMANENT, RT_SCOPE_LINK); 331 assertParcelingIsLossless(l); 332 } 333 334 @Test @IgnoreUpTo(Build.VERSION_CODES.Q) testLifetimeParceling()335 public void testLifetimeParceling() { 336 final LinkAddress l = new LinkAddress(V6_ADDRESS, 64, 123, 456, 1L, 3600000L); 337 assertParcelingIsLossless(l); 338 } 339 340 @Test @IgnoreAfter(Build.VERSION_CODES.Q) testFieldCount_Q()341 public void testFieldCount_Q() { 342 assertFieldCountEquals(4, LinkAddress.class); 343 } 344 345 @Test @IgnoreUpTo(Build.VERSION_CODES.Q) testFieldCount()346 public void testFieldCount() { 347 // Make sure any new field is covered by the above parceling tests when changing this number 348 assertFieldCountEquals(6, LinkAddress.class); 349 } 350 351 @Test @IgnoreUpTo(Build.VERSION_CODES.Q) testDeprecationTime()352 public void testDeprecationTime() { 353 try { 354 new LinkAddress(V6_ADDRESS, 64, 0, 456, 355 LinkAddress.LIFETIME_UNKNOWN, 100000L); 356 fail("Only one time provided should cause exception"); 357 } catch (IllegalArgumentException expected) { } 358 359 try { 360 new LinkAddress(V6_ADDRESS, 64, 0, 456, 361 200000L, 100000L); 362 fail("deprecation time later than expiration time should cause exception"); 363 } catch (IllegalArgumentException expected) { } 364 365 try { 366 new LinkAddress(V6_ADDRESS, 64, 0, 456, 367 -2, 100000L); 368 fail("negative deprecation time should cause exception"); 369 } catch (IllegalArgumentException expected) { } 370 371 LinkAddress addr = new LinkAddress(V6_ADDRESS, 64, 0, 456, 100000L, 200000L); 372 assertEquals(100000L, addr.getDeprecationTime()); 373 } 374 375 @Test @IgnoreUpTo(Build.VERSION_CODES.Q) testExpirationTime()376 public void testExpirationTime() { 377 try { 378 new LinkAddress(V6_ADDRESS, 64, 0, 456, 379 200000L, LinkAddress.LIFETIME_UNKNOWN); 380 fail("Only one time provided should cause exception"); 381 } catch (IllegalArgumentException expected) { } 382 383 try { 384 new LinkAddress(V6_ADDRESS, 64, 0, 456, 385 100000L, -2); 386 fail("negative expiration time should cause exception"); 387 } catch (IllegalArgumentException expected) { } 388 389 LinkAddress addr = new LinkAddress(V6_ADDRESS, 64, 0, 456, 100000L, 200000L); 390 assertEquals(200000L, addr.getExpirationTime()); 391 } 392 393 @Test testGetFlags()394 public void testGetFlags() { 395 LinkAddress l = new LinkAddress(V6_ADDRESS, 64, 123, RT_SCOPE_HOST); 396 assertEquals(123, l.getFlags()); 397 } 398 399 @Test @IgnoreUpTo(Build.VERSION_CODES.Q) testGetFlags_Deprecation()400 public void testGetFlags_Deprecation() { 401 // Test if deprecated bit was added/remove automatically based on the provided deprecation 402 // time 403 LinkAddress l = new LinkAddress(V6_ADDRESS, 64, 0, RT_SCOPE_HOST, 404 1L, LinkAddress.LIFETIME_PERMANENT); 405 // Check if the flag is added automatically. 406 assertTrue((l.getFlags() & IFA_F_DEPRECATED) != 0); 407 408 l = new LinkAddress(V6_ADDRESS, 64, IFA_F_DEPRECATED, RT_SCOPE_HOST, 409 SystemClock.elapsedRealtime() + 100000L, LinkAddress.LIFETIME_PERMANENT); 410 // Check if the flag is removed automatically. 411 assertTrue((l.getFlags() & IFA_F_DEPRECATED) == 0); 412 413 l = new LinkAddress(V6_ADDRESS, 64, IFA_F_DEPRECATED, RT_SCOPE_HOST, 414 LinkAddress.LIFETIME_PERMANENT, LinkAddress.LIFETIME_PERMANENT); 415 // Check if the permanent flag is added. 416 assertTrue((l.getFlags() & IFA_F_PERMANENT) != 0); 417 418 l = new LinkAddress(V6_ADDRESS, 64, IFA_F_PERMANENT, RT_SCOPE_HOST, 419 1000L, SystemClock.elapsedRealtime() + 100000L); 420 // Check if the permanent flag is removed 421 assertTrue((l.getFlags() & IFA_F_PERMANENT) == 0); 422 } 423 assertGlobalPreferred(LinkAddress l, String msg)424 private void assertGlobalPreferred(LinkAddress l, String msg) { 425 assertTrue(msg, l.isGlobalPreferred()); 426 } 427 assertNotGlobalPreferred(LinkAddress l, String msg)428 private void assertNotGlobalPreferred(LinkAddress l, String msg) { 429 assertFalse(msg, l.isGlobalPreferred()); 430 } 431 432 @Test testIsGlobalPreferred()433 public void testIsGlobalPreferred() { 434 LinkAddress l; 435 436 l = new LinkAddress(V4_ADDRESS, 32, 0, RT_SCOPE_UNIVERSE); 437 assertGlobalPreferred(l, "v4,global,noflags"); 438 439 l = new LinkAddress("10.10.1.7/23", 0, RT_SCOPE_UNIVERSE); 440 assertGlobalPreferred(l, "v4-rfc1918,global,noflags"); 441 442 l = new LinkAddress("10.10.1.7/23", 0, RT_SCOPE_SITE); 443 assertNotGlobalPreferred(l, "v4-rfc1918,site-local,noflags"); 444 445 l = new LinkAddress("127.0.0.7/8", 0, RT_SCOPE_HOST); 446 assertNotGlobalPreferred(l, "v4-localhost,node-local,noflags"); 447 448 l = new LinkAddress(V6_ADDRESS, 64, 0, RT_SCOPE_UNIVERSE); 449 assertGlobalPreferred(l, "v6,global,noflags"); 450 451 l = new LinkAddress(V6_ADDRESS, 64, IFA_F_PERMANENT, RT_SCOPE_UNIVERSE); 452 assertGlobalPreferred(l, "v6,global,permanent"); 453 454 // IPv6 ULAs are not acceptable "global preferred" addresses. 455 l = new LinkAddress("fc12::1/64", 0, RT_SCOPE_UNIVERSE); 456 assertNotGlobalPreferred(l, "v6,ula1,noflags"); 457 458 l = new LinkAddress("fd34::1/64", 0, RT_SCOPE_UNIVERSE); 459 assertNotGlobalPreferred(l, "v6,ula2,noflags"); 460 461 l = new LinkAddress(V6_ADDRESS, 64, IFA_F_TEMPORARY, RT_SCOPE_UNIVERSE); 462 assertGlobalPreferred(l, "v6,global,tempaddr"); 463 464 l = new LinkAddress(V6_ADDRESS, 64, (IFA_F_TEMPORARY|IFA_F_DADFAILED), 465 RT_SCOPE_UNIVERSE); 466 assertNotGlobalPreferred(l, "v6,global,tempaddr+dadfailed"); 467 468 l = new LinkAddress(V6_ADDRESS, 64, (IFA_F_TEMPORARY|IFA_F_DEPRECATED), 469 RT_SCOPE_UNIVERSE); 470 assertNotGlobalPreferred(l, "v6,global,tempaddr+deprecated"); 471 472 l = new LinkAddress(V6_ADDRESS, 64, IFA_F_TEMPORARY, RT_SCOPE_SITE); 473 assertNotGlobalPreferred(l, "v6,site-local,tempaddr"); 474 475 l = new LinkAddress(V6_ADDRESS, 64, IFA_F_TEMPORARY, RT_SCOPE_LINK); 476 assertNotGlobalPreferred(l, "v6,link-local,tempaddr"); 477 478 l = new LinkAddress(V6_ADDRESS, 64, IFA_F_TEMPORARY, RT_SCOPE_HOST); 479 assertNotGlobalPreferred(l, "v6,node-local,tempaddr"); 480 481 l = new LinkAddress("::1/128", IFA_F_PERMANENT, RT_SCOPE_HOST); 482 assertNotGlobalPreferred(l, "v6-localhost,node-local,permanent"); 483 484 l = new LinkAddress(V6_ADDRESS, 64, (IFA_F_TEMPORARY|IFA_F_TENTATIVE), 485 RT_SCOPE_UNIVERSE); 486 assertNotGlobalPreferred(l, "v6,global,tempaddr+tentative"); 487 488 l = new LinkAddress(V6_ADDRESS, 64, 489 (IFA_F_TEMPORARY|IFA_F_TENTATIVE|IFA_F_OPTIMISTIC), 490 RT_SCOPE_UNIVERSE); 491 assertGlobalPreferred(l, "v6,global,tempaddr+optimistic"); 492 } 493 494 @Test @IgnoreUpTo(Build.VERSION_CODES.Q) testIsGlobalPreferred_DeprecatedInFuture()495 public void testIsGlobalPreferred_DeprecatedInFuture() { 496 final LinkAddress l = new LinkAddress(V6_ADDRESS, 64, IFA_F_DEPRECATED, 497 RT_SCOPE_UNIVERSE, SystemClock.elapsedRealtime() + 100000, 498 SystemClock.elapsedRealtime() + 200000); 499 // Although the deprecated bit is set, but the deprecation time is in the future, test 500 // if the flag is removed automatically. 501 assertGlobalPreferred(l, "v6,global,tempaddr+deprecated in the future"); 502 } 503 } 504