Repository: rust
Issue: IPv6 Unicast Interface
Labels: C-tracking-issue,T-libs

This issue is split out of the larger discussion around stabilization of the `ip` feature (tracking issue: #27709). The focus of this issue on the question of what interface Rust should provide for IPv6 unicast adresses.

The current unstable interface is as follows:

```rust
impl Ipv6Addr {
    fn is_unicast_global(&self) -> bool;
    fn is_unicast_link_local(&self) -> bool;
    fn is_unicast_link_local_strict(&self) -> bool;
    fn is_unicast_site_local(&self) -> bool;
}
```

## Open Problems

### Behaviour of `is_unicast_link_local`/`is_unicast_link_local_strict`

Concern was raised about the need for both `is_unicast_link_local` and `is_unicast_link_local_strict`(https://github.com/rust-lang/rust/pull/66584#issuecomment-574036125). `is_unicast_link_local` tests if an address is in `FE80::/10`, `is_unicast_link_local_strict` in the stricter `FE80::/64`. For a time it was unclear which interpretation was the correct one, see https://github.com/rust-lang/rust/pull/76098#issue-475853748 for a more complete overview. However, it was mentioned (https://github.com/rust-lang/rust/pull/76098#issuecomment-705928605) that [IETF RFC #5156 Section 2.4](https://datatracker.ietf.org/doc/html/rfc5156#section-2.4) defines `FE80::/10` as the link-local unicast addresses, and that other programming languages and the linux kernel all use `FE80::/10` (https://github.com/rust-lang/rust/pull/76098#issuecomment-706916840, https://github.com/rust-lang/rust/pull/76098#issuecomment-705928605). The conclusion seems to be that the current implementation of `is_unicast_link_local` is correct and consistent with other implementations, `is_unicast_link_local_strict` could be removed.

Unresolved: Should `is_unicast_link_local_strict` be removed?

### Deprecation of site-local addresses

Unicast site-local addresses were deprecated in [IETF RFC #3879](https://datatracker.ietf.org/doc/html/rfc3879), see also [RFC #4291 Section 2.5.7](https://datatracker.ietf.org/doc/html/rfc4291#section-2.5.7). Any new implementation must no longer support the special behaviour of site-local addresses. This is mentioned in the docs of `is_unicast_site_local` and already implemented in `is_unicast_global`, which considers site-local addresses to be global.

For reference; .NET has [IsIPv6SiteLocal](https://docs.microsoft.com/en-us/dotnet/api/system.net.ipaddress.isipv6sitelocal?view=net-5.0), Python has [is_site_local](https://docs.python.org/3/library/ipaddress.html#ipaddress.IPv6Address.is_site_local) but mentions that is has been deprecated.

Unresolved: Should `is_unicast_site_local` be removed? Should `SiteLocal` be included in a possible `IPv6UnicastScope`?

### Introduce `IPv6UnicastScope`
It was suggested (https://github.com/rust-lang/rust/pull/76098#issuecomment-735019872) to replace the existing unicast interface with an enum `IPv6UnicastScope`, similar to `IPv6MulticastScope`:

```rust
impl Ipv6Addr {
    fn unicast_scope(&self) -> Option<IPv6UnicastScope>
}
```

Positive reaction (https://github.com/rust-lang/rust/pull/76098#issuecomment-735020358, https://github.com/rust-lang/rust/pull/76098#issuecomment-760762274)

Unresolved: What would be the definition of `IPv6UnicastScope`? 


## RFCs

- Unicast Adresses: [IETF RFC #4291 Section 2.5](https://datatracker.ietf.org/doc/html/rfc4291#section-2.5)
- Unique Local IPv6 Unicast Addresses: [IETF RFC #4193](https://datatracker.ietf.org/doc/html/rfc4193)
- Deprecating Site Local Addresses: [IETF RFC #3879](https://datatracker.ietf.org/doc/html/rfc3879)
- Special-Use IPv6 Addresses: [IETF RFC #5156](https://datatracker.ietf.org/doc/html/rfc5156)

## Previous Discussion

- stabilize the "ip" feature: [PR #66584](https://github.com/rust-lang/rust/pull/66584)
- Stabilize the "IP" feature: [PR #76098](https://github.com/rust-lang/rust/pull/76098)
- Stabilize the "IP" feature (continued from #76098): [PR #85585](https://github.com/rust-lang/rust/pull/85585)