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