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