// Copyright 2022 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

//! IPv6 Stateless Address Autoconfiguration (SLAAC) as defined by [RFC 4862]
//! and temporary address extensions for SLAAC as defined by [RFC 8981].
//!
//! [RFC 4862]: https://datatracker.ietf.org/doc/html/rfc4862
//! [RFC 8981]: https://datatracker.ietf.org/doc/html/rfc8981

use alloc::{boxed::Box, vec::Vec};
use core::{
    convert::TryFrom,
    num::{NonZeroU64, NonZeroU8},
    time::Duration,
};

use log::{debug, error, trace};
use net_types::{
    ip::{AddrSubnet, IpAddress, Ipv6, Ipv6Addr, Subnet},
    UnicastAddr, Witness as _,
};
use packet_formats::{icmp::ndp::NonZeroNdpLifetime, utils::NonZeroDuration};
use rand::{distributions::Uniform, Rng as _, RngCore};

use crate::{
    algorithm::{
        generate_opaque_interface_identifier, OpaqueIidNonce, STABLE_IID_SECRET_KEY_BYTES,
    },
    context::{CounterContext, InstantContext, RngContext, TimerContext, TimerHandler},
    error::ExistsError,
    ip::{
        device::state::{DelIpv6AddrReason, Lifetime, SlaacConfig, TemporarySlaacConfig},
        IpDeviceIdContext,
    },
    Instant,
};

/// Minimum Valid Lifetime value to actually update an address's valid lifetime.
///
/// 2 hours.
const MIN_PREFIX_VALID_LIFETIME_FOR_UPDATE: Duration = Duration::from_secs(7200);

/// Required prefix length for SLAAC.
///
/// We need 64 bits in the prefix because the interface identifier is 64 bits,
/// and IPv6 addresses are 128 bits.
const REQUIRED_PREFIX_BITS: u8 = 64;

// Host constants.

#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)]
enum InnerSlaacTimerId {
    /// Timer to deprecate an address configured via SLAAC.
    DeprecateSlaacAddress { addr: UnicastAddr<Ipv6Addr> },
    /// Timer to invalidate an address configured via SLAAC.
    InvalidateSlaacAddress { addr: UnicastAddr<Ipv6Addr> },
    /// Timer to generate a new temporary SLAAC address before an existing one
    /// expires.
    RegenerateTemporaryAddress { addr_subnet: AddrSubnet<Ipv6Addr, UnicastAddr<Ipv6Addr>> },
}

/// A timer ID for SLAAC.
#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)]
pub(crate) struct SlaacTimerId<DeviceId> {
    device_id: DeviceId,
    inner: InnerSlaacTimerId,
}

impl<DeviceId> SlaacTimerId<DeviceId> {
    pub(crate) fn new_deprecate_slaac_address(
        device_id: DeviceId,
        addr: UnicastAddr<Ipv6Addr>,
    ) -> SlaacTimerId<DeviceId> {
        SlaacTimerId { device_id, inner: InnerSlaacTimerId::DeprecateSlaacAddress { addr } }
    }

    pub(crate) fn new_invalidate_slaac_address(
        device_id: DeviceId,
        addr: UnicastAddr<Ipv6Addr>,
    ) -> SlaacTimerId<DeviceId> {
        SlaacTimerId { device_id, inner: InnerSlaacTimerId::InvalidateSlaacAddress { addr } }
    }

    pub(crate) fn new_regenerate_temporary_slaac_address(
        device_id: DeviceId,
        addr_subnet: AddrSubnet<Ipv6Addr, UnicastAddr<Ipv6Addr>>,
    ) -> SlaacTimerId<DeviceId> {
        SlaacTimerId {
            device_id,
            inner: InnerSlaacTimerId::RegenerateTemporaryAddress { addr_subnet },
        }
    }
}

/// The state associated with a SLAAC address.
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub(super) struct SlaacAddressEntry<Instant> {
    pub(super) addr_sub: AddrSubnet<Ipv6Addr, UnicastAddr<Ipv6Addr>>,
    pub(super) config: SlaacConfig<Instant>,
    pub(super) deprecated: bool,
}

/// A mutable view into state associated with a SLAAC address's mutable state.
pub(super) struct SlaacAddressEntryMut<'a, Instant> {
    pub(super) addr_sub: AddrSubnet<Ipv6Addr, UnicastAddr<Ipv6Addr>>,
    pub(super) config: &'a mut SlaacConfig<Instant>,
    pub(super) deprecated: &'a mut bool,
}

/// The state context provided to SLAAC.
pub(super) trait SlaacStateContext<C: SlaacNonSyncContext<Self::DeviceId>>:
    IpDeviceIdContext<Ipv6>
{
    /// Gets the configuration for SLAAC.
    fn get_config(&self, device_id: Self::DeviceId) -> SlaacConfiguration;

    /// Returns the number of DAD messages transmitted while performing DAD.
    ///
    /// `None` indicates that DAD is disabled.
    fn dad_transmits(&self, device_id: Self::DeviceId) -> Option<NonZeroU8>;

    /// Returns the configured NDP retransmission interval for the device.
    fn retrans_timer(&self, device_id: Self::DeviceId) -> Duration;

    /// Get the interface identifier for a device as defined by RFC 4291 section 2.5.1.
    fn get_interface_identifier(&self, device_id: Self::DeviceId) -> [u8; 8];

    /// Returns an iterator over the SLAAC addresses on the device.
    fn iter_slaac_addrs(
        &self,
        device_id: Self::DeviceId,
    ) -> Box<dyn Iterator<Item = SlaacAddressEntry<C::Instant>> + '_>;

    /// Returns an iterator providing a mutable view of mutable SLAAC address
    /// state.
    fn iter_slaac_addrs_mut(
        &mut self,
        device_id: Self::DeviceId,
    ) -> Box<dyn Iterator<Item = SlaacAddressEntryMut<'_, C::Instant>> + '_>;

    /// Adds a new IPv6 Global Address configured via SLAAC.
    fn add_slaac_addr_sub(
        &mut self,
        ctx: &mut C,
        device_id: Self::DeviceId,
        addr_sub: AddrSubnet<Ipv6Addr, UnicastAddr<Ipv6Addr>>,
        slaac_config: SlaacConfig<C::Instant>,
    ) -> Result<(), ExistsError>;

    /// Removes a SLAAC address.
    ///
    /// # Panics
    ///
    /// May panic if `addr` is not an address configured via SLAAC on
    /// `device_id`.
    fn remove_slaac_addr(
        &mut self,
        ctx: &mut C,
        device_id: Self::DeviceId,
        addr: &UnicastAddr<Ipv6Addr>,
    );
}

/// Update the instant at which an address configured via SLAAC is no longer
/// valid.
///
/// A `None` value for `valid_until` indicates that the address is valid
/// forever; `Some` indicates valid for some finite lifetime.
///
/// # Panics
///
/// May panic if `addr` is not an address configured via SLAAC on
/// `device_id`.
fn update_slaac_addr_valid_until<I: Instant>(
    slaac_config: &mut SlaacConfig<I>,
    valid_until: Lifetime<I>,
) {
    match slaac_config {
        SlaacConfig::Static { valid_until: v } => *v = valid_until,
        SlaacConfig::Temporary(TemporarySlaacConfig {
            valid_until: v,
            desync_factor: _,
            creation_time: _,
            dad_counter: _,
        }) => {
            *v = match valid_until {
                Lifetime::Finite(v) => v,
                Lifetime::Infinite => panic!("temporary addresses may not be valid forever"),
            }
        }
    };
}

/// The non-synchronized execution context for SLAAC.
pub(super) trait SlaacNonSyncContext<DeviceId>:
    RngContext + TimerContext<SlaacTimerId<DeviceId>>
{
}
impl<DeviceId, C: RngContext + TimerContext<SlaacTimerId<DeviceId>>> SlaacNonSyncContext<DeviceId>
    for C
{
}

/// The execution context for SLAAC.
trait SlaacContext<C: SlaacNonSyncContext<Self::DeviceId>>:
    SlaacStateContext<C> + CounterContext
{
}

impl<C: SlaacNonSyncContext<SC::DeviceId>, SC: SlaacStateContext<C> + CounterContext>
    SlaacContext<C> for SC
{
}

/// An implementation of SLAAC.
pub(crate) trait SlaacHandler<C: InstantContext>: IpDeviceIdContext<Ipv6> {
    /// Executes the algorithm in [RFC 4862 Section 5.5.3], with the extensions
    /// from [RFC 8981 Section 3.4] for temporary addresses, for a given prefix
    /// advertised by a router.
    ///
    /// This function updates all static and temporary SLAAC addresses for the
    /// given prefix and adds new ones if necessary.
    ///
    /// [RFC 4862 Section 5.5.3]: http://tools.ietf.org/html/rfc4862#section-5.5.3
    /// [RFC 8981 Section 3.4]: https://tools.ietf.org/html/rfc8981#section-3.4
    fn apply_slaac_update(
        &mut self,
        ctx: &mut C,
        device_id: Self::DeviceId,
        prefix: Subnet<Ipv6Addr>,
        preferred_lifetime: Option<NonZeroNdpLifetime>,
        valid_lifetime: Option<NonZeroNdpLifetime>,
    );

    /// Handles SLAAC specific aspects of address removal.
    ///
    /// Must only be called after the address is removed from the interface.
    fn on_address_removed(
        &mut self,
        ctx: &mut C,
        device_id: Self::DeviceId,
        addr: AddrSubnet<Ipv6Addr, UnicastAddr<Ipv6Addr>>,
        state: SlaacConfig<C::Instant>,
        reason: DelIpv6AddrReason,
    );

    /// Removes all SLAAC addresses assigned to the device.
    fn remove_all_slaac_addresses(&mut self, ctx: &mut C, device_id: Self::DeviceId);
}

impl<C: SlaacNonSyncContext<SC::DeviceId>, SC: SlaacContext<C>> SlaacHandler<C> for SC {
    fn apply_slaac_update(
        &mut self,
        ctx: &mut C,
        device_id: Self::DeviceId,
        subnet: Subnet<Ipv6Addr>,
        preferred_lifetime: Option<NonZeroNdpLifetime>,
        valid_lifetime: Option<NonZeroNdpLifetime>,
    ) {
        if preferred_lifetime > valid_lifetime {
            // If the preferred lifetime is greater than the valid lifetime,
            // silently ignore the Prefix Information option, as per RFC 4862
            // section 5.5.3.
            trace!("receive_ndp_packet: autonomous prefix's preferred lifetime is greater than valid lifetime, ignoring");
            return;
        }

        let mut seen_static = false;
        let mut seen_temporary = false;

        let now = ctx.now();
        let config = self.get_config(device_id);
        let dad_transmits = self.dad_transmits(device_id);
        let retrans_timer = self.retrans_timer(device_id);

        // Apply the update to each existing address, static or temporary, for the
        // prefix.
        for entry in self.iter_slaac_addrs_mut(device_id).filter(|a| a.addr_sub.subnet() == subnet)
        {
            let addr_sub = entry.addr_sub;
            let addr = addr_sub.addr();
            let slaac_config = &entry.config;
            let slaac_type = SlaacType::from(&**slaac_config);

            trace!(
                "receive_ndp_packet: already have a {:?} SLAAC address {:?} configured on device {:?}",
                slaac_type,
                addr_sub,
                device_id
            );

            // Mark the SLAAC address type as existing so we know not to
            // generate an address for the type later.
            //
            // Note that SLAAC addresses are never invalidated/removed in
            // response to a prefix update and addresses types never change
            // after the address is added.
            match slaac_type {
                SlaacType::Static => seen_static = true,
                SlaacType::Temporary => seen_temporary = true,
            }

            /// Encapsulates a lifetime bound and where it came from.
            #[derive(Copy, Clone)]
            enum ValidLifetimeBound {
                FromPrefix(Option<NonZeroNdpLifetime>),
                FromMaxBound(Duration),
            }

            impl ValidLifetimeBound {
                /// Unwraps the object and returns the wrapped duration.
                fn get(self) -> Option<NonZeroNdpLifetime> {
                    match self {
                        Self::FromPrefix(d) => d,
                        Self::FromMaxBound(d) => {
                            NonZeroDuration::new(d).map(NonZeroNdpLifetime::Finite)
                        }
                    }
                }
            }

            let (valid_for, entry_valid_until, preferred_for_and_regen_at) = match slaac_config {
                SlaacConfig::Static { valid_until: entry_valid_until } => (
                    ValidLifetimeBound::FromPrefix(valid_lifetime),
                    *entry_valid_until,
                    preferred_lifetime.map(|p| (p, None)),
                ),
                // Select valid_for and preferred_for according to RFC 8981
                // Section 3.4.
                SlaacConfig::Temporary(TemporarySlaacConfig {
                    valid_until: entry_valid_until,
                    creation_time,
                    desync_factor,
                    dad_counter: _,
                }) => {
                    let SlaacConfiguration {
                        enable_stable_addresses: _,
                        temporary_address_configuration,
                    } = config;
                    let (valid_for, preferred_for, entry_valid_until) =
                        match temporary_address_configuration {
                            // Since it's possible to change NDP configuration for a
                            // device during runtime, we can end up here, with a
                            // temporary address on an interface even though temporary
                            // addressing is disabled. Setting its validity period to 0
                            // will force it to be removed ASAP.
                            None => (
                                ValidLifetimeBound::FromMaxBound(Duration::ZERO),
                                None,
                                *entry_valid_until,
                            ),
                            Some(temporary_address_config) => {
                                // RFC 8981 Section 3.4.2:
                                //   When updating the preferred lifetime of an existing
                                //   temporary address, it would be set to expire at
                                //   whichever time is earlier: the time indicated by
                                //   the received lifetime or (CREATION_TIME +
                                //   TEMP_PREFERRED_LIFETIME - DESYNC_FACTOR). A similar
                                //   approach can be used with the valid lifetime.
                                let preferred_for =
                                    preferred_lifetime.and_then(|preferred_lifetime| {
                                        temporary_address_config
                                            .temp_preferred_lifetime
                                            .get()
                                            .checked_sub(now.duration_since(*creation_time))
                                            .and_then(|p| p.checked_sub(*desync_factor))
                                            .and_then(NonZeroDuration::new)
                                            .map(|d| preferred_lifetime.min_finite_duration(d))
                                    });
                                // Per RFC 8981 Section 3.4.1, `desync_factor` is only
                                // used for preferred lifetime:
                                //   [...] with the overall constraint that no temporary
                                //   addresses should ever remain "valid" or "preferred"
                                //   for a time longer than (TEMP_VALID_LIFETIME) or
                                //   (TEMP_PREFERRED_LIFETIME - DESYNC_FACTOR),
                                //   respectively.
                                let since_creation = now.duration_since(*creation_time);
                                let configured_max_lifetime =
                                    temporary_address_config.temp_valid_lifetime.get();
                                let max_valid_lifetime = if since_creation > configured_max_lifetime
                                {
                                    Duration::ZERO
                                } else {
                                    configured_max_lifetime - since_creation
                                };

                                let valid_for = valid_lifetime.map_or(
                                    ValidLifetimeBound::FromPrefix(None),
                                    |d| match d {
                                        NonZeroNdpLifetime::Infinite => {
                                            ValidLifetimeBound::FromMaxBound(max_valid_lifetime)
                                        }
                                        NonZeroNdpLifetime::Finite(d) => {
                                            if max_valid_lifetime <= d.get() {
                                                ValidLifetimeBound::FromMaxBound(max_valid_lifetime)
                                            } else {
                                                ValidLifetimeBound::FromPrefix(valid_lifetime)
                                            }
                                        }
                                    },
                                );

                                (valid_for, preferred_for, *entry_valid_until)
                            }
                        };

                    let preferred_for_and_regen_at = preferred_for.map(|preferred_for| {
                        let SlaacConfiguration {
                            enable_stable_addresses: _,
                            temporary_address_configuration,
                        } = config;

                        let regen_at = temporary_address_configuration.and_then(
                            |TemporarySlaacAddressConfiguration {
                                 temp_idgen_retries,
                                 temp_preferred_lifetime: _,
                                 temp_valid_lifetime: _,
                                 secret_key: _,
                             }| {
                                let regen_advance = regen_advance(
                                    temp_idgen_retries,
                                    retrans_timer,
                                    dad_transmits.map_or(0, NonZeroU8::get),
                                )
                                .get();
                                // Per RFC 8981 Section 3.6:
                                //
                                //   Hosts following this specification SHOULD
                                //   generate new temporary addresses over time.
                                //   This can be achieved by generating a new
                                //   temporary address REGEN_ADVANCE time units
                                //   before a temporary address becomes deprecated.
                                //
                                // It's possible for regen_at to be before the
                                // current time. In that case, set it to `now` so
                                // that a new address is generated after the current
                                // prefix information is handled.
                                preferred_for
                                    .get()
                                    .checked_sub(regen_advance)
                                    .map_or(Some(now), |d| now.checked_add(d))
                            },
                        );

                        (NonZeroNdpLifetime::Finite(preferred_for), regen_at)
                    });

                    (valid_for, Lifetime::Finite(entry_valid_until), preferred_for_and_regen_at)
                }
            };

            // `Some` iff the remaining lifetime is a positive non-zero lifetime.
            let remaining_lifetime = match entry_valid_until {
                Lifetime::Infinite => Some(Lifetime::Infinite),
                Lifetime::Finite(entry_valid_until) => (entry_valid_until > now)
                    .then(|| Lifetime::Finite(entry_valid_until.duration_since(now))),
            };

            // As per RFC 4862 section 5.5.3.e, if the advertised prefix is equal to
            // the prefix of an address configured by stateless autoconfiguration in
            // the list, the preferred lifetime of the address is reset to the
            // Preferred Lifetime in the received advertisement.

            // Update the preferred lifetime for this address.
            match preferred_for_and_regen_at {
                None => {
                    if !*entry.deprecated {
                        *entry.deprecated = true;
                        let _: Option<C::Instant> = ctx.cancel_timer(
                            SlaacTimerId::new_deprecate_slaac_address(device_id, addr),
                        );
                        let _: Option<C::Instant> =
                            ctx.cancel_timer(SlaacTimerId::new_regenerate_temporary_slaac_address(
                                device_id, addr_sub,
                            ));
                    }
                }
                Some((preferred_for, regen_at)) => {
                    if *entry.deprecated {
                        *entry.deprecated = false;
                    }

                    let timer_id =
                        SlaacTimerId::new_deprecate_slaac_address(device_id, addr).into();
                    let _previously_scheduled_instant: Option<C::Instant> = match preferred_for {
                        NonZeroNdpLifetime::Finite(preferred_for) => {
                            // Use `schedule_timer_instant` instead of `schedule_timer` to set
                            // the timeout relative to the previously recorded `now` value. This
                            // helps prevent skew in cases where this task gets preempted and
                            // isn't scheduled for some period of time between recording `now`
                            // and here.
                            ctx.schedule_timer_instant(
                                now.checked_add(preferred_for.get()).unwrap(),
                                timer_id,
                            )
                        }
                        NonZeroNdpLifetime::Infinite => ctx.cancel_timer(timer_id),
                    };

                    let _prev_regen_at: Option<C::Instant> = match regen_at {
                        Some(regen_at) => ctx.schedule_timer_instant(
                            regen_at,
                            SlaacTimerId::new_regenerate_temporary_slaac_address(
                                device_id, addr_sub,
                            ),
                        ),
                        None => {
                            ctx.cancel_timer(SlaacTimerId::new_regenerate_temporary_slaac_address(
                                device_id, addr_sub,
                            ))
                        }
                    };
                }
            }

            // As per RFC 4862 section 5.5.3.e, the specific action to perform for
            // the valid lifetime of the address depends on the Valid Lifetime in
            // the received advertisement and the remaining time to the valid
            // lifetime expiration of the previously autoconfigured address:
            let valid_for_to_update = match valid_for {
                ValidLifetimeBound::FromMaxBound(valid_for) => {
                    // If the maximum lifetime for the address is smaller than the
                    // lifetime specified for the prefix, then it must be applied.
                    NonZeroDuration::new(valid_for).map(NonZeroNdpLifetime::Finite)
                }
                ValidLifetimeBound::FromPrefix(valid_for) => {
                    // If the received Valid Lifetime is greater than 2 hours or
                    // greater than RemainingLifetime, set the valid lifetime of
                    // the corresponding address to the advertised Valid
                    // Lifetime.
                    match valid_for {
                        Some(NonZeroNdpLifetime::Infinite) => Some(NonZeroNdpLifetime::Infinite),
                        Some(NonZeroNdpLifetime::Finite(v))
                            if v.get() > MIN_PREFIX_VALID_LIFETIME_FOR_UPDATE
                                || remaining_lifetime
                                    .map_or(true, |r| r < Lifetime::Finite(v.get())) =>
                        {
                            Some(NonZeroNdpLifetime::Finite(v))
                        }
                        None | Some(NonZeroNdpLifetime::Finite(_)) => {
                            if remaining_lifetime.map_or(true, |r| {
                                r <= Lifetime::Finite(MIN_PREFIX_VALID_LIFETIME_FOR_UPDATE)
                            }) {
                                // If RemainingLifetime is less than or equal to 2 hours,
                                // ignore the Prefix Information option with regards to the
                                // valid lifetime, unless the Router Advertisement from
                                // which this option was obtained has been authenticated
                                // (e.g., via Secure Neighbor Discovery [RFC3971]).  If the
                                // Router Advertisement was authenticated, the valid
                                // lifetime of the corresponding address should be set to
                                // the Valid Lifetime in the received option.
                                //
                                // TODO(ghanan): If the NDP packet this prefix option is in
                                //               was authenticated, update the valid
                                //               lifetime of the address to the valid
                                //               lifetime in the received option, as per RFC
                                //               4862 section 5.5.3.e.
                                None
                            } else {
                                // Otherwise, reset the valid lifetime of the corresponding
                                // address to 2 hours.
                                Some(NonZeroNdpLifetime::Finite(
                                    NonZeroDuration::new(MIN_PREFIX_VALID_LIFETIME_FOR_UPDATE)
                                        .unwrap(),
                                ))
                            }
                        }
                    }
                }
            };

            match valid_for_to_update {
                Some(valid_for) => match valid_for {
                    NonZeroNdpLifetime::Finite(valid_for) => {
                        let valid_until = now.checked_add(valid_for.get()).unwrap();
                        trace!("receive_ndp_packet: updating valid lifetime to {:?} for SLAAC address {:?} on device {:?}", valid_until, addr, device_id);

                        // Set the valid lifetime for this address.

                        update_slaac_addr_valid_until(entry.config, Lifetime::Finite(valid_until));

                        let _: Option<C::Instant> = ctx.schedule_timer_instant(
                            valid_until,
                            SlaacTimerId::new_invalidate_slaac_address(device_id, addr).into(),
                        );
                    }
                    NonZeroNdpLifetime::Infinite => {
                        // Set the valid lifetime for this address.
                        update_slaac_addr_valid_until(entry.config, Lifetime::Infinite);

                        let _: Option<C::Instant> = ctx.cancel_timer(
                            SlaacTimerId::new_invalidate_slaac_address(device_id, addr).into(),
                        );
                    }
                },
                None => {
                    trace!("receive_ndp_packet: not updating valid lifetime for SLAAC address {:?} on device {:?} as remaining lifetime is less than 2 hours and new valid lifetime ({:?}) is less than remaining lifetime", addr, device_id, valid_for.get());
                }
            }
        }

        // As per RFC 4862 section 5.5.3.e, if the prefix advertised is not equal to
        // the prefix of an address configured by stateless autoconfiguration
        // already in the list of addresses associated with the interface, and if
        // the Valid Lifetime is not 0, form an address (and add it to the list) by
        // combining the advertised prefix with an interface identifier of the link
        // as follows:
        //
        // |    128 - N bits    |        N bits          |
        // +--------------------+------------------------+
        // |    link prefix     |  interface identifier  |
        // +---------------------------------------------+
        let valid_lifetime = match valid_lifetime {
            Some(valid_lifetime) => valid_lifetime,
            None => {
                trace!("receive_ndp_packet: autonomous prefix has valid lifetime = 0, ignoring");
                return;
            }
        };

        let address_types_to_add = (!seen_static)
            .then(|| {
                // As per RFC 4862 Section 5.5.3.d,
                //
                //
                //   If the prefix advertised is not equal to the prefix of an
                //   address configured by stateless autoconfiguration already
                //   in the list of addresses associated with the interface
                //   (where 'equal' means the two prefix lengths are the same
                //   and the first prefix- length bits of the prefixes are
                //   identical), and if the Valid Lifetime is not 0, form an
                //   address [...].
                SlaacType::Static
            })
            .into_iter()
            .chain(
                (!seen_temporary)
                    .then(|| {
                        // As per RFC 8981 Section 3.4.3,
                        //
                        //   If the host has not configured any temporary
                        //   address for the corresponding prefix, the host
                        //   SHOULD create a new temporary address for such
                        //   prefix.
                        SlaacType::Temporary
                    })
                    .into_iter(),
            );

        for slaac_type in address_types_to_add {
            add_slaac_addr_sub(
                self,
                ctx,
                device_id,
                now,
                SlaacInitConfig::new(slaac_type),
                valid_lifetime,
                preferred_lifetime,
                &subnet,
            );
        }
    }

    fn on_address_removed(
        &mut self,
        ctx: &mut C,
        device_id: Self::DeviceId,
        addr_sub: AddrSubnet<Ipv6Addr, UnicastAddr<Ipv6Addr>>,
        state: SlaacConfig<C::Instant>,
        reason: DelIpv6AddrReason,
    ) {
        let preferred_until =
            ctx.cancel_timer(SlaacTimerId::new_deprecate_slaac_address(device_id, addr_sub.addr()));
        let _valid_until: Option<C::Instant> = ctx
            .cancel_timer(SlaacTimerId::new_invalidate_slaac_address(device_id, addr_sub.addr()));

        let TemporarySlaacConfig { valid_until, creation_time, desync_factor, dad_counter } =
            match state {
                SlaacConfig::Temporary(temporary_config) => {
                    let _regen_at: Option<C::Instant> = ctx.cancel_timer(
                        SlaacTimerId::new_regenerate_temporary_slaac_address(device_id, addr_sub),
                    );
                    temporary_config
                }
                SlaacConfig::Static { .. } => return,
            };

        match reason {
            DelIpv6AddrReason::ManualAction => return,
            DelIpv6AddrReason::DadFailed => {
                // Attempt to regenerate the address.
            }
        }

        let SlaacConfiguration { enable_stable_addresses: _, temporary_address_configuration } =
            self.get_config(device_id);
        let temporary_address_configuration = match temporary_address_configuration {
            Some(configuration) => configuration,
            None => return,
        };

        if dad_counter >= temporary_address_configuration.temp_idgen_retries {
            return;
        }

        let temp_valid_lifetime = temporary_address_configuration.temp_valid_lifetime;
        // Compute the original preferred lifetime for the removed address so that
        // it can be used for the new address being generated. If, when the address
        // was created, the prefix's preferred lifetime was less than
        // `temporary_address_configuration.temp_preferred_lifetime`, then that's
        // what will be calculated here. That's fine because it's a lower bound on
        // the prefix's value, which means the prefix's value is still being
        // respected.
        let preferred_for = match preferred_until
            .map(|preferred_until| preferred_until.duration_since(creation_time) + desync_factor)
        {
            Some(preferred_for) => preferred_for,
            // If the address is already deprecated, a new address should already
            // have been generated, so ignore this one.
            None => return,
        };

        let now = ctx.now();
        // It's possible this `valid_for` value is larger than `temp_valid_lifetime`
        // (e.g. if the NDP configuration was changed since this address was
        // generated). That's okay, because `add_slaac_addr_sub` will apply the
        // current maximum valid lifetime when called below.
        let valid_for = NonZeroDuration::new(valid_until.duration_since(creation_time))
            .unwrap_or(temp_valid_lifetime);

        add_slaac_addr_sub(
            self,
            ctx,
            device_id,
            now,
            SlaacInitConfig::Temporary { dad_count: dad_counter + 1 },
            NonZeroNdpLifetime::Finite(valid_for),
            NonZeroDuration::new(preferred_for).map(NonZeroNdpLifetime::Finite),
            &addr_sub.subnet(),
        );
    }

    fn remove_all_slaac_addresses(&mut self, ctx: &mut C, device_id: Self::DeviceId) {
        self.iter_slaac_addrs(device_id)
            .map(|a| a.addr_sub.addr())
            .collect::<Vec<_>>()
            .into_iter()
            .for_each(|addr| {
                self.remove_slaac_addr(ctx, device_id, &addr);
            })
    }
}

impl<C: SlaacNonSyncContext<SC::DeviceId>, SC: SlaacContext<C>>
    TimerHandler<C, SlaacTimerId<SC::DeviceId>> for SC
{
    fn handle_timer(
        &mut self,
        ctx: &mut C,
        SlaacTimerId { device_id, inner }: SlaacTimerId<SC::DeviceId>,
    ) {
        match inner {
            InnerSlaacTimerId::DeprecateSlaacAddress { addr } => {
                set_deprecated_slaac_addr(self, device_id, &addr, true)
            }
            InnerSlaacTimerId::InvalidateSlaacAddress { addr } => {
                self.remove_slaac_addr(ctx, device_id, &addr);
            }
            InnerSlaacTimerId::RegenerateTemporaryAddress { addr_subnet } => {
                regenerate_temporary_slaac_addr(self, ctx, device_id, &addr_subnet);
            }
        }
    }
}

/// Configuration values for SLAAC temporary addressing.
///
/// The algorithm specified in [RFC 8981 Section 3.4] references several
/// configuration parameters, which are defined in [Section 3.8] and
/// [Section 3.3.2] This struct contains the following values specified by the
/// RFC:
/// - TEMP_VALID_LIFETIME
/// - TEMP_PREFERRED_LIFETIME
/// - TEMP_IDGEN_RETRIES
/// - secret_key
///
/// [RFC 8981 Section 3.4]: http://tools.ietf.org/html/rfc8981#section-3.4
/// [Section 3.3.2]: http://tools.ietf.org/html/rfc8981#section-3.3.2
/// [Section 3.8]: http://tools.ietf.org/html/rfc8981#section-3.8
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub struct TemporarySlaacAddressConfiguration {
    /// The maximum amount of time that a temporary address can be considered
    /// valid, from the time of its creation.
    pub temp_valid_lifetime: NonZeroDuration,

    /// The maximum amount of time that a temporary address can be preferred,
    /// from the time of its creation.
    pub temp_preferred_lifetime: NonZeroDuration,

    /// The number of times to attempt to pick a new temporary address after DAD
    /// detects a duplicate before stopping and giving up on temporary address
    /// generation for that prefix.
    pub temp_idgen_retries: u8,

    /// The secret to use when generating new temporary addresses. This should
    /// be initialized from a random number generator before generating any
    /// temporary addresses.
    pub secret_key: [u8; STABLE_IID_SECRET_KEY_BYTES],
}

/// The configuration for SLAAC.
#[derive(Copy, Clone, Debug, Default, Eq, PartialEq)]
pub struct SlaacConfiguration {
    /// Configuration to enable stable address assignment.
    pub enable_stable_addresses: bool,

    /// Configuration for temporary address assignment.
    ///
    /// If `None`, temporary addresses will not be assigned to interfaces, and
    /// any already-assigned temporary addresses will be removed.
    ///
    /// If Some, specifies the configuration parameters for temporary addressing,
    /// including those relating to how long temporary addresses should remain
    /// preferred and valid.
    pub temporary_address_configuration: Option<TemporarySlaacAddressConfiguration>,
}

#[derive(PartialEq, Eq)]
enum SlaacType {
    Static,
    Temporary,
}

impl core::fmt::Debug for SlaacType {
    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
        match self {
            SlaacType::Static => f.write_str("static"),
            SlaacType::Temporary => f.write_str("temporary"),
        }
    }
}

impl<'a, Instant> From<&'a SlaacConfig<Instant>> for SlaacType {
    fn from(slaac_config: &'a SlaacConfig<Instant>) -> Self {
        match slaac_config {
            SlaacConfig::Static { .. } => SlaacType::Static,
            SlaacConfig::Temporary { .. } => SlaacType::Temporary,
        }
    }
}

fn set_deprecated_slaac_addr<C: SlaacNonSyncContext<SC::DeviceId>, SC: SlaacContext<C>>(
    sync_ctx: &mut SC,
    device_id: SC::DeviceId,
    addr: &UnicastAddr<Ipv6Addr>,
    deprecated: bool,
) {
    let entry =
        sync_ctx.iter_slaac_addrs_mut(device_id).find(|a| &a.addr_sub.addr() == addr).unwrap();
    *entry.deprecated = deprecated;
}

/// The minimum REGEN_ADVANCE as specified in [RFC 8981 Section 3.8].
///
/// [RFC 8981 Section 3.8]: https://datatracker.ietf.org/doc/html/rfc8981#section-3.8
// As per [RFC 8981 Section 3.8],
//
//   REGEN_ADVANCE
//      2 + (TEMP_IDGEN_RETRIES * DupAddrDetectTransmits * RetransTimer /
//      1000)
//
//      ..., such that REGEN_ADVANCE is expressed in seconds.
const MIN_REGEN_ADVANCE: NonZeroDuration =
    NonZeroDuration::from_nonzero_secs(const_unwrap::const_unwrap_option(NonZeroU64::new(2)));

/// Computes REGEN_ADVANCE as specified in [RFC 8981 Section 3.8].
///
/// [RFC 8981 Section 3.8]: http://tools.ietf.org/html/rfc8981#section-3.8
fn regen_advance(
    temp_idgen_retries: u8,
    retrans_timer: Duration,
    dad_transmits: u8,
) -> NonZeroDuration {
    // Per the RFC, REGEN_ADVANCE in seconds =
    //   2 + (TEMP_IDGEN_RETRIES * DupAddrDetectTransmits * RetransTimer / 1000)
    //
    // where RetransTimer is in milliseconds. Since values here are kept as
    // Durations, there is no need to apply scale factors.
    MIN_REGEN_ADVANCE
        + retrans_timer
            .checked_mul(u32::from(temp_idgen_retries) * u32::from(dad_transmits))
            .unwrap_or(Duration::ZERO)
}

/// Computes the DESYNC_FACTOR as specified in [RFC 8981 section 3.8].
///
/// Per the RFC,
///
///    DESYNC_FACTOR
///       A random value within the range 0 - MAX_DESYNC_FACTOR.  It
///       is computed each time a temporary address is generated, and
///       is associated with the corresponding address.  It MUST be
///       smaller than (TEMP_PREFERRED_LIFETIME - REGEN_ADVANCE).
///
/// Returns `None` if a DESYNC_FACTOR value cannot be calculated. This will
/// occur when REGEN_ADVANCE is larger than TEMP_PREFERRED_LIFETIME as no valid
/// DESYNC_FACTOR exists that is greater than or equal to 0.
///
/// [RFC 8981 Section 3.8]: http://tools.ietf.org/html/rfc8981#section-3.8
fn desync_factor<R: RngCore>(
    rng: &mut R,
    temp_preferred_lifetime: NonZeroDuration,
    regen_advance: NonZeroDuration,
) -> Option<Duration> {
    let temp_preferred_lifetime = temp_preferred_lifetime.get();

    // Per RFC 8981 Section 3.8:
    //    MAX_DESYNC_FACTOR
    //       0.4 * TEMP_PREFERRED_LIFETIME.  Upper bound on DESYNC_FACTOR.
    //
    //       |  Rationale: Setting MAX_DESYNC_FACTOR to 0.4
    //       |  TEMP_PREFERRED_LIFETIME results in addresses that have
    //       |  statistically different lifetimes, and a maximum of three
    //       |  concurrent temporary addresses when the default values
    //       |  specified in this section are employed.
    //    DESYNC_FACTOR
    //       A random value within the range 0 - MAX_DESYNC_FACTOR.  It
    //       is computed each time a temporary address is generated, and
    //       is associated with the corresponding address.  It MUST be
    //       smaller than (TEMP_PREFERRED_LIFETIME - REGEN_ADVANCE).
    temp_preferred_lifetime.checked_sub(regen_advance.get()).map(|max_desync_factor| {
        let max_desync_factor =
            core::cmp::min(max_desync_factor, (temp_preferred_lifetime * 2) / 5);
        rng.sample(Uniform::new(Duration::ZERO, max_desync_factor))
    })
}

fn regenerate_temporary_slaac_addr<C: SlaacNonSyncContext<SC::DeviceId>, SC: SlaacContext<C>>(
    sync_ctx: &mut SC,
    ctx: &mut C,
    device_id: SC::DeviceId,
    addr_subnet: &AddrSubnet<Ipv6Addr, UnicastAddr<Ipv6Addr>>,
) {
    let entry = {
        let mut subnet_addrs = sync_ctx
            .iter_slaac_addrs(device_id)
            .filter(|entry| entry.addr_sub.subnet() == addr_subnet.subnet() && !entry.deprecated);

        // It's possible that there are multiple non-deprecated temporary
        // addresses in a subnet for this host (if prefix updates are received
        // after regen but before deprecation). Per RFC 8981 Section 3.5:
        //
        //   Note that, in normal operation, except for the transient period
        //   when a temporary address is being regenerated, at most one
        //   temporary address per prefix should be in a nondeprecated state at
        //   any given time on a given interface.
        //
        // In order to tend towards only one non-deprecated temporary address on
        // a subnet, we ignore all but the last regen timer for the
        // non-deprecated addresses in a subnet.
        if let Some((entry, regen_at)) = subnet_addrs.find_map(|entry| {
            ctx.scheduled_instant(SlaacTimerId::new_regenerate_temporary_slaac_address(
                device_id,
                entry.addr_sub,
            ))
            .map(|instant| (entry, instant))
        }) {
            debug!(
                "regenerate_temporary_addr: ignoring regen event at {:?} for {:?} since {:?} will regenerate after at {:?}",
                ctx.now(), addr_subnet, entry.addr_sub.addr(), regen_at);
            return;
        }
        match sync_ctx.iter_slaac_addrs(device_id).find(|entry| &entry.addr_sub == addr_subnet) {
            Some(entry) => entry,
            None => unreachable!("couldn't find {:?} to regenerate", addr_subnet),
        }
    };
    assert!(!entry.deprecated, "can't regenerate deprecated address {:?}", addr_subnet);

    let TemporarySlaacConfig { creation_time, desync_factor, valid_until, dad_counter: _ } =
        match entry.config {
            SlaacConfig::Temporary(temporary_config) => temporary_config,
            SlaacConfig::Static { valid_until: _ } => unreachable!(
                "can't regenerate a temporary address for {:?}, which is static",
                addr_subnet
            ),
        };

    let SlaacConfiguration { enable_stable_addresses: _, temporary_address_configuration } =
        sync_ctx.get_config(device_id);
    let TemporarySlaacAddressConfiguration {
        temp_valid_lifetime,
        temp_preferred_lifetime: _,
        temp_idgen_retries: _,
        secret_key: _,
    } = match temporary_address_configuration {
        Some(configuration) => configuration,
        None => return,
    };

    let deprecate_at = ctx
        .scheduled_instant(SlaacTimerId::new_deprecate_slaac_address(device_id, addr_subnet.addr()))
        .unwrap_or_else(|| unreachable!(
            "temporary SLAAC address {:?} had a regen timer fire but does not have a deprecation timer",
            addr_subnet.addr()
        ));
    let preferred_for = deprecate_at.duration_since(creation_time) + desync_factor;

    let now = ctx.now();
    // It's possible this `valid_for` value is larger than `temp_valid_lifetime`
    // (e.g. if the NDP configuration was changed since this address was
    // generated). That's okay, because `add_slaac_addr_sub` will apply the
    // current maximum valid lifetime when called below.
    let valid_for = NonZeroDuration::new(valid_until.duration_since(creation_time))
        .unwrap_or(temp_valid_lifetime);

    add_slaac_addr_sub(
        sync_ctx,
        ctx,
        device_id,
        now,
        SlaacInitConfig::Temporary { dad_count: 0 },
        NonZeroNdpLifetime::Finite(valid_for),
        NonZeroDuration::new(preferred_for).map(NonZeroNdpLifetime::Finite),
        &addr_subnet.subnet(),
    );
}

#[derive(Copy, Clone, Debug)]
enum SlaacInitConfig {
    Static,
    Temporary { dad_count: u8 },
}

impl SlaacInitConfig {
    fn new(slaac_type: SlaacType) -> Self {
        match slaac_type {
            SlaacType::Static => Self::Static,
            SlaacType::Temporary => Self::Temporary { dad_count: 0 },
        }
    }
}

/// Checks whether the address has an IID that doesn't conflict with existing
/// IANA reserved ranges.
///
/// Compares against the ranges defined by various RFCs and listed at
/// https://www.iana.org/assignments/ipv6-interface-ids/ipv6-interface-ids.xhtml
fn has_iana_allowed_iid(address: Ipv6Addr) -> bool {
    let mut iid = [0u8; 8];
    const U64_SUFFIX_LEN: usize = Ipv6Addr::BYTES as usize - u64::BITS as usize / 8;
    iid.copy_from_slice(&address.bytes()[U64_SUFFIX_LEN..]);
    let iid = u64::from_be_bytes(iid);
    match iid {
        // Subnet-Router Anycast
        0x0000_0000_0000_0000 => false,
        // Consolidated match for
        // - Ethernet Block: 0x200:5EFF:FE00:0000-0200:4EFF:FE00:5212
        // - Proxy Mobile: 0x200:5EFF:FE00:5213
        // - Ethernet Block: 0x200:5EFF:FE00:5214-0200:4EFF:FEFF:FFFF
        0x0200_5EFF_FE00_0000..=0x0200_5EFF_FEFF_FFFF => false,
        // Subnet Anycast Addresses
        0xFDFF_FFFF_FFFF_FF80..=0xFDFF_FFFF_FFFF_FFFF => false,

        // All other IIDs not in the reserved ranges
        _iid => true,
    }
}

/// Generate an IPv6 Global Address as defined by RFC 4862 section 5.5.3.d.
///
/// The generated address will be of the format:
///
/// |            128 - N bits               |       N bits           |
/// +---------------------------------------+------------------------+
/// |            link prefix                |  interface identifier  |
/// +----------------------------------------------------------------+
///
/// # Panics
///
/// Panics if a valid IPv6 unicast address cannot be formed with the provided
/// prefix and interface identifier, or if the prefix length is not a multiple
/// of 8 bits.
fn generate_global_static_address(
    prefix: &Subnet<Ipv6Addr>,
    iid: &[u8],
) -> AddrSubnet<Ipv6Addr, UnicastAddr<Ipv6Addr>> {
    if prefix.prefix() % 8 != 0 {
        unimplemented!("generate_global_address: not implemented for when prefix length is not a multiple of 8 bits");
    }

    let prefix_len = prefix.prefix() / u8::try_from(u8::BITS).unwrap();

    assert_eq!(usize::from(Ipv6Addr::BYTES - prefix_len), iid.len());

    let mut address = prefix.network().ipv6_bytes();
    address[prefix_len.into()..].copy_from_slice(&iid);

    let address = AddrSubnet::new(Ipv6Addr::from(address), prefix.prefix()).unwrap();
    assert_eq!(address.subnet(), *prefix);

    address
}

/// Generate a temporary IPv6 Global Address as defined by RFC 8981 section 3.4.6
///
/// The generated address will be of the format:
///
/// |            128 - N bits              |        N bits           |
/// +--------------------------------------+-------------------------+
/// |            link prefix               |  randomized identifier  |
/// +----------------------------------------------------------------+
///
/// # Panics
///
/// Panics if a valid IPv6 unicast address cannot be formed with the provided
/// prefix, or if the prefix length is not a multiple of 8 bits.
fn generate_global_temporary_address(
    prefix: &Subnet<Ipv6Addr>,
    iid: &[u8; 8],
    seed: u64,
    secret_key: &[u8; STABLE_IID_SECRET_KEY_BYTES],
) -> AddrSubnet<Ipv6Addr, UnicastAddr<Ipv6Addr>> {
    let prefix_len = usize::from(prefix.prefix() / 8);

    assert_eq!(usize::from(Ipv6Addr::BYTES) - prefix_len, iid.len());
    let mut address = prefix.network().ipv6_bytes();

    let interface_identifier = generate_opaque_interface_identifier(
        /* prefix */ *prefix,
        /* net_iface */ iid,
        /* net_id */ [],
        /* nonce */ OpaqueIidNonce::Random(seed),
        /* secret_key */ secret_key,
    );
    let suffix_bytes = &interface_identifier.to_be_bytes()[..(address.len() - prefix_len)];
    address[prefix_len..].copy_from_slice(suffix_bytes);

    let address = AddrSubnet::new(Ipv6Addr::from(address), prefix.prefix()).unwrap();
    assert_eq!(address.subnet(), *prefix);

    address
}

fn add_slaac_addr_sub<C: SlaacNonSyncContext<SC::DeviceId>, SC: SlaacContext<C>>(
    sync_ctx: &mut SC,
    ctx: &mut C,
    device_id: SC::DeviceId,
    now: C::Instant,
    slaac_config: SlaacInitConfig,
    prefix_valid_for: NonZeroNdpLifetime,
    prefix_preferred_for: Option<NonZeroNdpLifetime>,
    subnet: &Subnet<Ipv6Addr>,
) {
    if subnet.prefix() != REQUIRED_PREFIX_BITS {
        // If the sum of the prefix length and interface identifier length does
        // not equal 128 bits, the Prefix Information option MUST be ignored, as
        // per RFC 4862 section 5.5.3.
        error!("receive_ndp_packet: autonomous prefix length {:?} and interface identifier length {:?} cannot form valid IPv6 address, ignoring", subnet.prefix(), REQUIRED_PREFIX_BITS);
        return;
    }

    struct PreferredForAndRegenAt<Instant>(NonZeroNdpLifetime, Option<Instant>);

    let SlaacConfiguration { enable_stable_addresses, temporary_address_configuration } =
        sync_ctx.get_config(device_id);

    let (valid_until, preferred_and_regen, slaac_config, mut addresses) = match slaac_config {
        SlaacInitConfig::Static => {
            if !enable_stable_addresses {
                trace!("stable SLAAC addresses are disabled on device {:?}", device_id);
                return;
            }

            let valid_until = match prefix_valid_for {
                NonZeroNdpLifetime::Finite(d) => {
                    Lifetime::Finite(now.checked_add(d.get()).unwrap())
                }
                NonZeroNdpLifetime::Infinite => Lifetime::Infinite,
            };
            (
                valid_until,
                prefix_preferred_for.map(|p| PreferredForAndRegenAt(p, None)),
                SlaacConfig::Static { valid_until },
                // Generate the global address as defined by RFC 4862 section 5.5.3.d.
                //
                // TODO(https://fxbug.dev/95946): Support regenerating address.
                either::Either::Left(core::iter::once(generate_global_static_address(
                    &subnet,
                    &sync_ctx.get_interface_identifier(device_id)[..],
                ))),
            )
        }
        SlaacInitConfig::Temporary { dad_count } => {
            let temporary_address_config = match temporary_address_configuration {
                Some(temporary_address_config) => temporary_address_config,
                None => {
                    trace!(
                        "receive_ndp_packet: temporary addresses are disabled on device {:?}",
                        device_id
                    );
                    return;
                }
            };

            let per_attempt_random_seed = ctx.rng_mut().next_u64();
            let dad_transmits = sync_ctx.dad_transmits(device_id);

            // Per RFC 8981 Section 3.4.4:
            //    When creating a temporary address, DESYNC_FACTOR MUST be computed
            //    and associated with the newly created address, and the address
            //    lifetime values MUST be derived from the corresponding prefix as
            //    follows:
            //
            //    *  Its valid lifetime is the lower of the Valid Lifetime of the
            //       prefix and TEMP_VALID_LIFETIME.
            //
            //    *  Its preferred lifetime is the lower of the Preferred Lifetime
            //       of the prefix and TEMP_PREFERRED_LIFETIME - DESYNC_FACTOR.
            let valid_for = match prefix_valid_for {
                NonZeroNdpLifetime::Finite(prefix_valid_for) => {
                    core::cmp::min(prefix_valid_for, temporary_address_config.temp_valid_lifetime)
                }
                NonZeroNdpLifetime::Infinite => temporary_address_config.temp_valid_lifetime,
            };

            let regen_advance = regen_advance(
                temporary_address_config.temp_idgen_retries,
                sync_ctx.retrans_timer(device_id),
                dad_transmits.map_or(0, NonZeroU8::get),
            );

            let iid = sync_ctx.get_interface_identifier(device_id);
            let secret_key = temporary_address_config.secret_key;
            let mut seed = per_attempt_random_seed;
            let addresses = either::Either::Right(core::iter::repeat_with(move || {
                // RFC 8981 Section 3.3.3 specifies that
                //
                //   The resulting IID MUST be compared against the reserved
                //   IPv6 IIDs and against those IIDs already employed in an
                //   address of the same network interface and the same network
                //   prefix.  In the event that an unacceptable identifier has
                //   been generated, the DAD_Counter should be incremented by 1,
                //   and the algorithm should be restarted from the first step.
                loop {
                    let address =
                        generate_global_temporary_address(&subnet, &iid, seed, &secret_key);
                    seed = seed.wrapping_add(1);

                    if has_iana_allowed_iid(address.addr().get()) {
                        break address;
                    }
                }
            }));

            let valid_until = now.checked_add(valid_for.get()).unwrap();

            let desync_factor = if let Some(d) = desync_factor(
                ctx.rng_mut(),
                temporary_address_config.temp_preferred_lifetime,
                regen_advance,
            ) {
                d
            } else {
                // We only fail to calculate a desync factor when the configured
                // maximum temporary address preferred lifetime is less than
                // REGEN_ADVANCE and per RFC 8981 Section 3.4.5,
                //
                //   A temporary address is created only if this calculated
                //   preferred lifetime is greater than REGEN_ADVANCE time
                //   units.
                trace!(
                    "failed to calculate DESYNC_FACTOR; temp_preferred_lifetime={:?}, regen_advance={:?}",
                    temporary_address_config.temp_preferred_lifetime,
                    regen_advance,
                );
                return;
            };

            let preferred_for = prefix_preferred_for.and_then(|prefix_preferred_for| {
                temporary_address_config
                    .temp_preferred_lifetime
                    .get()
                    .checked_sub(desync_factor)
                    .and_then(NonZeroDuration::new)
                    .map(|d| prefix_preferred_for.min_finite_duration(d))
            });

            // RFC 8981 Section 3.4.5:
            //
            //   A temporary address is created only if this calculated
            //   preferred lifetime is greater than REGEN_ADVANCE time
            //   units.
            let preferred_for_and_regen_at = match preferred_for {
                None => return,
                Some(preferred_for) => match preferred_for.get().checked_sub(regen_advance.get()) {
                    Some(before_regen) => PreferredForAndRegenAt(
                        NonZeroNdpLifetime::Finite(preferred_for),
                        Some(now.checked_add(before_regen).unwrap()),
                    ),
                    None => {
                        trace!("receive_ndp_packet: preferred lifetime of {:?} for subnet {:?} is too short to allow regen", preferred_for, subnet);
                        return;
                    }
                },
            };

            (
                Lifetime::Finite(valid_until),
                Some(preferred_for_and_regen_at),
                SlaacConfig::Temporary(TemporarySlaacConfig {
                    desync_factor,
                    valid_until,
                    creation_time: now,
                    dad_counter: dad_count,
                }),
                addresses,
            )
        }
    };

    // Attempt to add the address to the device.
    let address = loop {
        let address = match addresses.next() {
            Some(address) => address,
            // No more addresses to try - do nothing further.
            None => {
                trace!(
                    "exhausted possible SLAAC addresses without assigning on device {:?}",
                    device_id
                );
                return;
            }
        };

        // TODO(https://fxbug.dev/91301): Should bindings be the one to actually
        // assign the address to maintain a "single source of truth"?
        match sync_ctx.add_slaac_addr_sub(ctx, device_id, address, slaac_config) {
            Err(ExistsError) => {
                trace!("IPv6 SLAAC address {:?} already exists on device {:?}", address, device_id);

                // Try the next address.
                //
                // TODO(https://fxbug.dev/100003): Limit number of attempts.
                sync_ctx.increment_counter("generated_slaac_addr_exists");
            }
            Ok(()) => break address,
        }
    };

    trace!("receive_ndp_packet: Successfully configured new IPv6 address {:?} on device {:?} via SLAAC", address, device_id);

    // Set the valid lifetime for this address.
    //
    // Must not have reached this point if the address was already assigned
    // to a device.
    match valid_until {
        Lifetime::Finite(valid_until) => {
            assert_eq!(
                ctx.schedule_timer_instant(
                    valid_until,
                    SlaacTimerId::new_invalidate_slaac_address(device_id, address.addr()).into(),
                ),
                None
            );
        }
        Lifetime::Infinite => {}
    }

    let deprecate_timer_id = SlaacTimerId::new_deprecate_slaac_address(device_id, address.addr());

    // Set the preferred lifetime for this address.
    //
    // Must not have reached this point if the address was already assigned
    // to a device.
    match preferred_and_regen {
        // Use `schedule_timer_instant` instead of `schedule_timer` to set the timeout
        // relative to the previously recorded `now` value. This helps prevent skew in
        // cases where this task gets preempted and isn't scheduled for some period of time
        // between recording `now` and here.
        Some(PreferredForAndRegenAt(preferred_for, regen_at)) => {
            match preferred_for {
                NonZeroNdpLifetime::Finite(preferred_for) => {
                    assert_eq!(
                        ctx.schedule_timer_instant(
                            now.checked_add(preferred_for.get()).unwrap(),
                            deprecate_timer_id.into()
                        ),
                        None
                    );
                }
                NonZeroNdpLifetime::Infinite => {}
            }

            match regen_at {
                Some(regen_at) => assert_eq!(
                    ctx.schedule_timer_instant(
                        regen_at,
                        SlaacTimerId::new_regenerate_temporary_slaac_address(device_id, address)
                            .into()
                    ),
                    None
                ),
                None => (),
            }
        }
        None => {
            set_deprecated_slaac_addr(sync_ctx, device_id, &address.addr(), true);
            assert_eq!(ctx.cancel_timer(deprecate_timer_id.into()), None);
        }
    };
}

#[cfg(test)]
mod tests {
    use core::convert::TryFrom as _;

    use assert_matches::assert_matches;
    use net_declare::net::ip_v6;
    use net_types::{ethernet::Mac, ip::Ip as _, LinkLocalAddress as _};
    use packet::{Buf, InnerPacketBuilder as _, Serializer as _};
    use packet_formats::{
        icmp::{
            ndp::{
                options::{NdpOptionBuilder, PrefixInformation},
                OptionSequenceBuilder, RouterAdvertisement,
            },
            IcmpPacketBuilder, IcmpUnusedCode,
        },
        ip::Ipv6Proto,
        ipv6::Ipv6PacketBuilder,
    };
    use test_case::test_case;

    use super::*;
    use crate::{
        context::testutil::{
            DummyCtx, DummyInstant, DummyInstantRange as _v, DummyNonSyncCtx, DummySyncCtx,
            DummyTimerCtxExt as _,
        },
        device::FrameDestination,
        ip::{
            device::{
                get_assigned_ipv6_addr_subnets, integration::REQUIRED_NDP_IP_PACKET_HOP_LIMIT,
            },
            receive_ipv6_packet, DummyDeviceId,
        },
        testutil::{assert_empty, DummyEventDispatcherConfig, FakeCryptoRng, TestIpExt as _},
        Ctx,
    };

    struct MockSlaacContext {
        config: SlaacConfiguration,
        dad_transmits: Option<NonZeroU8>,
        retrans_timer: Duration,
        iid: [u8; 8],
        slaac_addrs: Vec<SlaacAddressEntry<DummyInstant>>,
        non_slaac_addr: Option<UnicastAddr<Ipv6Addr>>,
    }

    type MockCtx = DummySyncCtx<MockSlaacContext, (), DummyDeviceId>;
    type MockNonSyncCtx = DummyNonSyncCtx<SlaacTimerId<DummyDeviceId>, (), ()>;

    impl SlaacStateContext<MockNonSyncCtx> for MockCtx {
        fn get_config(&self, DummyDeviceId: Self::DeviceId) -> SlaacConfiguration {
            let MockSlaacContext {
                config,
                dad_transmits: _,
                retrans_timer: _,
                iid: _,
                slaac_addrs: _,
                non_slaac_addr: _,
            } = self.get_ref();
            *config
        }

        fn dad_transmits(&self, DummyDeviceId: Self::DeviceId) -> Option<NonZeroU8> {
            let MockSlaacContext {
                config: _,
                dad_transmits,
                retrans_timer: _,
                iid: _,
                slaac_addrs: _,
                non_slaac_addr: _,
            } = self.get_ref();
            *dad_transmits
        }

        fn retrans_timer(&self, DummyDeviceId: Self::DeviceId) -> Duration {
            let MockSlaacContext {
                config: _,
                dad_transmits: _,
                retrans_timer,
                iid: _,
                slaac_addrs: _,
                non_slaac_addr: _,
            } = self.get_ref();
            *retrans_timer
        }

        fn get_interface_identifier(&self, DummyDeviceId: Self::DeviceId) -> [u8; 8] {
            let MockSlaacContext {
                config: _,
                dad_transmits: _,
                retrans_timer: _,
                iid,
                slaac_addrs: _,
                non_slaac_addr: _,
            } = self.get_ref();
            *iid
        }

        fn iter_slaac_addrs(
            &self,
            DummyDeviceId: Self::DeviceId,
        ) -> Box<dyn Iterator<Item = SlaacAddressEntry<DummyInstant>> + '_> {
            let MockSlaacContext {
                config: _,
                dad_transmits: _,
                retrans_timer: _,
                iid: _,
                slaac_addrs,
                non_slaac_addr: _,
            } = self.get_ref();
            Box::new(slaac_addrs.iter().cloned())
        }

        fn iter_slaac_addrs_mut(
            &mut self,
            DummyDeviceId: Self::DeviceId,
        ) -> Box<dyn Iterator<Item = SlaacAddressEntryMut<'_, DummyInstant>> + '_> {
            let MockSlaacContext {
                config: _,
                dad_transmits: _,
                retrans_timer: _,
                iid: _,
                slaac_addrs,
                non_slaac_addr: _,
            } = self.get_mut();
            Box::new(slaac_addrs.iter_mut().map(
                |SlaacAddressEntry { addr_sub, config, deprecated }| SlaacAddressEntryMut {
                    addr_sub: *addr_sub,
                    config,
                    deprecated,
                },
            ))
        }

        fn add_slaac_addr_sub(
            &mut self,
            _ctx: &mut MockNonSyncCtx,
            DummyDeviceId: Self::DeviceId,
            addr_sub: AddrSubnet<Ipv6Addr, UnicastAddr<Ipv6Addr>>,
            config: SlaacConfig<DummyInstant>,
        ) -> Result<(), ExistsError> {
            let MockSlaacContext {
                config: _,
                dad_transmits: _,
                retrans_timer: _,
                iid: _,
                slaac_addrs,
                non_slaac_addr,
            } = self.get_mut();

            if non_slaac_addr.map_or(false, |a| a == addr_sub.addr()) {
                return Err(ExistsError);
            }

            if slaac_addrs.iter().any(|e| e.addr_sub.addr() == addr_sub.addr()) {
                return Err(ExistsError);
            }

            slaac_addrs.push(SlaacAddressEntry { addr_sub, config, deprecated: false });
            Ok(())
        }

        fn remove_slaac_addr(
            &mut self,
            _ctx: &mut MockNonSyncCtx,
            DummyDeviceId: Self::DeviceId,
            addr: &UnicastAddr<Ipv6Addr>,
        ) {
            let MockSlaacContext {
                config: _,
                dad_transmits: _,
                retrans_timer: _,
                iid: _,
                slaac_addrs,
                non_slaac_addr: _,
            } = self.get_mut();

            slaac_addrs.retain(|e| &e.addr_sub.addr() != addr)
        }
    }

    #[test_case(ip_v6!("1:2:3:4::"), false; "subnet-router anycast")]
    #[test_case(ip_v6!("::1"), true; "allowed 1")]
    #[test_case(ip_v6!("1:2:3:4::1"), true; "allowed 2")]
    #[test_case(ip_v6!("4:4:4:4:0200:5eff:fe00:1"), false; "first ethernet block")]
    #[test_case(ip_v6!("1:1:1:1:0200:5eff:fe00:5213"), false; "proxy mobile")]
    #[test_case(ip_v6!("8:8:8:8:0200:5eff:fe00:8000"), false; "second ethernet block")]
    #[test_case(ip_v6!("a:a:a:a:fdff:ffff:ffff:ffaa"), false; "subnet anycast")]
    #[test_case(ip_v6!("c:c:c:c:fe00::"), true; "allowed 3")]
    fn test_has_iana_allowed_iid(addr: Ipv6Addr, expect_allowed: bool) {
        assert_eq!(has_iana_allowed_iid(addr), expect_allowed);
    }

    const IID: [u8; 8] = [0, 1, 2, 3, 4, 5, 6, 7];
    const DEFAULT_RETRANS_TIMER: Duration = Duration::from_secs(1);
    const SUBNET: Subnet<Ipv6Addr> =
        unsafe { Subnet::new_unchecked(Ipv6Addr::new([0x200a, 0, 0, 0, 0, 0, 0, 0]), 64) };

    #[test_case(0, 0, true; "zero lifetimes")]
    #[test_case(2, 1, true; "preferred larger than valid")]
    #[test_case(1, 2, false; "disabled")]
    fn dont_generate_address(
        preferred_lifetime_secs: u32,
        valid_lifetime_secs: u32,
        enable_stable_addresses: bool,
    ) {
        let DummyCtx { mut sync_ctx, mut non_sync_ctx } =
            DummyCtx::with_sync_ctx(MockCtx::with_state(MockSlaacContext {
                config: SlaacConfiguration { enable_stable_addresses, ..Default::default() },
                dad_transmits: None,
                retrans_timer: DEFAULT_RETRANS_TIMER,
                iid: IID,
                slaac_addrs: Default::default(),
                non_slaac_addr: None,
            }));

        SlaacHandler::apply_slaac_update(
            &mut sync_ctx,
            &mut non_sync_ctx,
            DummyDeviceId,
            SUBNET,
            NonZeroNdpLifetime::from_u32_with_infinite(preferred_lifetime_secs),
            NonZeroNdpLifetime::from_u32_with_infinite(valid_lifetime_secs),
        );
        assert_empty(sync_ctx.iter_slaac_addrs(DummyDeviceId));
        non_sync_ctx.timer_ctx().assert_no_timers_installed();
    }

    fn calculate_addr_sub(
        subnet: Subnet<Ipv6Addr>,
        iid: [u8; 8],
    ) -> AddrSubnet<Ipv6Addr, UnicastAddr<Ipv6Addr>> {
        let mut bytes = subnet.network().ipv6_bytes();
        bytes[8..].copy_from_slice(&iid);
        AddrSubnet::new(Ipv6Addr::from_bytes(bytes), subnet.prefix()).unwrap()
    }

    #[test_case(0; "deprecated")]
    #[test_case(1; "preferred")]
    fn generate_stable_address(preferred_lifetime_secs: u32) {
        let DummyCtx { mut sync_ctx, mut non_sync_ctx } =
            DummyCtx::with_sync_ctx(MockCtx::with_state(MockSlaacContext {
                config: SlaacConfiguration { enable_stable_addresses: true, ..Default::default() },
                dad_transmits: None,
                retrans_timer: DEFAULT_RETRANS_TIMER,
                iid: IID,
                slaac_addrs: Default::default(),
                non_slaac_addr: None,
            }));

        let valid_lifetime_secs = preferred_lifetime_secs + 1;
        let addr_sub = calculate_addr_sub(SUBNET, IID);

        // Generate a new SLAAC address.
        SlaacHandler::apply_slaac_update(
            &mut sync_ctx,
            &mut non_sync_ctx,
            DummyDeviceId,
            SUBNET,
            NonZeroNdpLifetime::from_u32_with_infinite(preferred_lifetime_secs),
            NonZeroNdpLifetime::from_u32_with_infinite(valid_lifetime_secs),
        );
        let address_created_deprecated = preferred_lifetime_secs == 0;
        let now = non_sync_ctx.now();
        let valid_until = now + Duration::from_secs(valid_lifetime_secs.into());
        let entry = SlaacAddressEntry {
            addr_sub,
            config: SlaacConfig::Static { valid_until: Lifetime::Finite(valid_until) },
            deprecated: address_created_deprecated,
        };
        assert_eq!(sync_ctx.iter_slaac_addrs(DummyDeviceId).collect::<Vec<_>>(), [entry],);
        let deprecate_timer_id =
            SlaacTimerId::new_deprecate_slaac_address(DummyDeviceId, addr_sub.addr());
        let invalidate_timer_id =
            SlaacTimerId::new_invalidate_slaac_address(DummyDeviceId, addr_sub.addr());
        if address_created_deprecated {
            non_sync_ctx.timer_ctx().assert_timers_installed([(invalidate_timer_id, valid_until)]);
        } else {
            non_sync_ctx.timer_ctx().assert_timers_installed([
                (deprecate_timer_id, now + Duration::from_secs(preferred_lifetime_secs.into())),
                (invalidate_timer_id, valid_until),
            ]);

            // Trigger the deprecation timer.
            assert_eq!(
                non_sync_ctx.trigger_next_timer(&mut sync_ctx, TimerHandler::handle_timer),
                Some(deprecate_timer_id)
            );
            let entry = SlaacAddressEntry { deprecated: true, ..entry };
            assert_eq!(sync_ctx.iter_slaac_addrs(DummyDeviceId).collect::<Vec<_>>(), [entry],);
            non_sync_ctx.timer_ctx().assert_timers_installed([(invalidate_timer_id, valid_until)]);
        }

        // Trigger the invalidation timer.
        assert_eq!(
            non_sync_ctx.trigger_next_timer(&mut sync_ctx, TimerHandler::handle_timer),
            Some(invalidate_timer_id)
        );
        assert_empty(sync_ctx.iter_slaac_addrs(DummyDeviceId));
        non_sync_ctx.timer_ctx().assert_no_timers_installed();
    }

    #[test]
    fn stable_address_conflict() {
        let addr_sub = calculate_addr_sub(SUBNET, IID);

        let DummyCtx { mut sync_ctx, mut non_sync_ctx } =
            DummyCtx::with_sync_ctx(MockCtx::with_state(MockSlaacContext {
                config: SlaacConfiguration { enable_stable_addresses: true, ..Default::default() },
                dad_transmits: None,
                retrans_timer: DEFAULT_RETRANS_TIMER,
                iid: IID,
                slaac_addrs: Default::default(),
                // Consider the address we will generate as already assigned without
                // SLAAC.
                non_slaac_addr: Some(addr_sub.addr()),
            }));

        const LIFETIME_SECS: u32 = 1;

        // Generate a new SLAAC address.
        SlaacHandler::apply_slaac_update(
            &mut sync_ctx,
            &mut non_sync_ctx,
            DummyDeviceId,
            SUBNET,
            NonZeroNdpLifetime::from_u32_with_infinite(LIFETIME_SECS),
            NonZeroNdpLifetime::from_u32_with_infinite(LIFETIME_SECS),
        );
        assert_empty(sync_ctx.iter_slaac_addrs(DummyDeviceId));
        non_sync_ctx.timer_ctx().assert_no_timers_installed();
    }

    #[test_case(DelIpv6AddrReason::ManualAction; "manual action")]
    #[test_case(DelIpv6AddrReason::DadFailed; "dad failed")]
    fn remove_stable_address(reason: DelIpv6AddrReason) {
        let addr_sub = calculate_addr_sub(SUBNET, IID);

        let DummyCtx { mut sync_ctx, mut non_sync_ctx } =
            DummyCtx::with_sync_ctx(MockCtx::with_state(MockSlaacContext {
                config: SlaacConfiguration { enable_stable_addresses: true, ..Default::default() },
                dad_transmits: None,
                retrans_timer: DEFAULT_RETRANS_TIMER,
                iid: IID,
                slaac_addrs: Default::default(),
                non_slaac_addr: None,
            }));

        const LIFETIME_SECS: u32 = 1;

        // Generate a new SLAAC address.
        SlaacHandler::apply_slaac_update(
            &mut sync_ctx,
            &mut non_sync_ctx,
            DummyDeviceId,
            SUBNET,
            NonZeroNdpLifetime::from_u32_with_infinite(LIFETIME_SECS),
            NonZeroNdpLifetime::from_u32_with_infinite(LIFETIME_SECS),
        );
        let now = non_sync_ctx.now();
        let valid_until = now + Duration::from_secs(LIFETIME_SECS.into());
        let entry = SlaacAddressEntry {
            addr_sub,
            config: SlaacConfig::Static { valid_until: Lifetime::Finite(valid_until) },
            deprecated: false,
        };
        assert_eq!(sync_ctx.iter_slaac_addrs(DummyDeviceId).collect::<Vec<_>>(), [entry],);
        let deprecate_timer_id =
            SlaacTimerId::new_deprecate_slaac_address(DummyDeviceId, addr_sub.addr());
        let invalidate_timer_id =
            SlaacTimerId::new_invalidate_slaac_address(DummyDeviceId, addr_sub.addr());
        non_sync_ctx.timer_ctx().assert_timers_installed([
            (deprecate_timer_id, now + Duration::from_secs(LIFETIME_SECS.into())),
            (invalidate_timer_id, valid_until),
        ]);

        // Remove the address and let SLAAC know the address was removed
        let config = {
            let SlaacAddressEntry { addr_sub: got_addr_sub, config, deprecated } =
                sync_ctx.get_mut().slaac_addrs.remove(0);
            assert_eq!(addr_sub, got_addr_sub);
            assert!(!deprecated);
            config
        };
        SlaacHandler::on_address_removed(
            &mut sync_ctx,
            &mut non_sync_ctx,
            DummyDeviceId,
            addr_sub,
            config,
            reason,
        );
        non_sync_ctx.timer_ctx().assert_no_timers_installed();
    }

    struct RefreshStableAddressTimersTest {
        orig_pl_secs: u32,
        orig_vl_secs: u32,
        new_pl_secs: u32,
        new_vl_secs: u32,
        effective_new_vl_secs: u32,
    }

    const ONE_HOUR_AS_SECS: u32 = 60 * 60;
    const TWO_HOURS_AS_SECS: u32 = ONE_HOUR_AS_SECS * 2;
    const THREE_HOURS_AS_SECS: u32 = ONE_HOUR_AS_SECS * 3;
    const INFINITE_LIFETIME: u32 = u32::MAX;
    const MIN_PREFIX_VALID_LIFETIME_FOR_UPDATE_AS_SECS: u32 =
        MIN_PREFIX_VALID_LIFETIME_FOR_UPDATE.as_secs() as u32;
    #[test_case(RefreshStableAddressTimersTest {
        orig_pl_secs: 1,
        orig_vl_secs: 1,
        new_pl_secs: 1,
        new_vl_secs: 1,
        effective_new_vl_secs: 1,
    }; "do nothing")]
    #[test_case(RefreshStableAddressTimersTest {
        orig_pl_secs: 1,
        orig_vl_secs: 1,
        new_pl_secs: 2,
        new_vl_secs: 2,
        effective_new_vl_secs: 2,
    }; "increase lifetimes")]
    #[test_case(RefreshStableAddressTimersTest {
        orig_pl_secs: 1,
        orig_vl_secs: 1,
        new_pl_secs: 0,
        new_vl_secs: 1,
        effective_new_vl_secs: 1,
    }; "deprecate address only")]
    #[test_case(RefreshStableAddressTimersTest {
        orig_pl_secs: 0,
        orig_vl_secs: 1,
        new_pl_secs: 1,
        new_vl_secs: 1,
        effective_new_vl_secs: 1,
    }; "undeprecate address")]
    #[test_case(RefreshStableAddressTimersTest {
        orig_pl_secs: 1,
        orig_vl_secs: 1,
        new_pl_secs: 0,
        new_vl_secs: 0,
        effective_new_vl_secs: 1,
    }; "deprecate address only with new valid lifetime of zero")]
    #[test_case(RefreshStableAddressTimersTest {
        orig_pl_secs: ONE_HOUR_AS_SECS,
        orig_vl_secs: ONE_HOUR_AS_SECS,
        new_pl_secs: ONE_HOUR_AS_SECS - 1,
        new_vl_secs: ONE_HOUR_AS_SECS - 1,
        effective_new_vl_secs: ONE_HOUR_AS_SECS,
    }; "decrease preferred lifetime and ignore new valid lifetime if less than 2 hours and remaining lifetime")]
    #[test_case(RefreshStableAddressTimersTest {
        orig_pl_secs: THREE_HOURS_AS_SECS,
        orig_vl_secs: THREE_HOURS_AS_SECS,
        new_pl_secs: MIN_PREFIX_VALID_LIFETIME_FOR_UPDATE_AS_SECS - 1,
        new_vl_secs: MIN_PREFIX_VALID_LIFETIME_FOR_UPDATE_AS_SECS - 1,
        effective_new_vl_secs: MIN_PREFIX_VALID_LIFETIME_FOR_UPDATE_AS_SECS,
    }; "deprecate address only and bring valid lifetime down to 2 hours at max")]
    #[test_case(RefreshStableAddressTimersTest {
        orig_pl_secs: ONE_HOUR_AS_SECS - 1,
        orig_vl_secs: ONE_HOUR_AS_SECS - 1,
        new_pl_secs: ONE_HOUR_AS_SECS - 1,
        new_vl_secs: ONE_HOUR_AS_SECS,
        effective_new_vl_secs: ONE_HOUR_AS_SECS,
    }; "increase valid lifetime if more than remaining valid lifetime")]
    #[test_case(RefreshStableAddressTimersTest {
        orig_pl_secs: INFINITE_LIFETIME,
        orig_vl_secs: INFINITE_LIFETIME,
        new_pl_secs: INFINITE_LIFETIME,
        new_vl_secs: INFINITE_LIFETIME,
        effective_new_vl_secs: INFINITE_LIFETIME,
    }; "infinite lifetimes")]
    #[test_case(RefreshStableAddressTimersTest {
        orig_pl_secs: ONE_HOUR_AS_SECS,
        orig_vl_secs: TWO_HOURS_AS_SECS,
        new_pl_secs: TWO_HOURS_AS_SECS,
        new_vl_secs: INFINITE_LIFETIME,
        effective_new_vl_secs: INFINITE_LIFETIME,
    }; "update valid lifetime from finite to infinite")]
    #[test_case(RefreshStableAddressTimersTest {
        orig_pl_secs: ONE_HOUR_AS_SECS,
        orig_vl_secs: TWO_HOURS_AS_SECS,
        new_pl_secs: INFINITE_LIFETIME,
        new_vl_secs: INFINITE_LIFETIME,
        effective_new_vl_secs: INFINITE_LIFETIME,
    }; "update both lifetimes from finite to infinite")]
    #[test_case(RefreshStableAddressTimersTest {
        orig_pl_secs: TWO_HOURS_AS_SECS,
        orig_vl_secs: INFINITE_LIFETIME,
        new_pl_secs: ONE_HOUR_AS_SECS,
        new_vl_secs: MIN_PREFIX_VALID_LIFETIME_FOR_UPDATE_AS_SECS - 1,
        effective_new_vl_secs: MIN_PREFIX_VALID_LIFETIME_FOR_UPDATE_AS_SECS,
    }; "update valid lifetime from infinite to finite")]
    #[test_case(RefreshStableAddressTimersTest {
        orig_pl_secs: INFINITE_LIFETIME,
        orig_vl_secs: INFINITE_LIFETIME,
        new_pl_secs: ONE_HOUR_AS_SECS,
        new_vl_secs: MIN_PREFIX_VALID_LIFETIME_FOR_UPDATE_AS_SECS - 1,
        effective_new_vl_secs: MIN_PREFIX_VALID_LIFETIME_FOR_UPDATE_AS_SECS,
    }; "update both lifetimes from infinite to finite")]
    fn stable_address_timers(
        RefreshStableAddressTimersTest {
            orig_pl_secs,
            orig_vl_secs,
            new_pl_secs,
            new_vl_secs,
            effective_new_vl_secs,
        }: RefreshStableAddressTimersTest,
    ) {
        let DummyCtx { mut sync_ctx, mut non_sync_ctx } =
            DummyCtx::with_sync_ctx(MockCtx::with_state(MockSlaacContext {
                config: SlaacConfiguration { enable_stable_addresses: true, ..Default::default() },
                dad_transmits: None,
                retrans_timer: DEFAULT_RETRANS_TIMER,
                iid: IID,
                slaac_addrs: Default::default(),
                non_slaac_addr: None,
            }));

        let addr_sub = calculate_addr_sub(SUBNET, IID);
        let deprecate_timer_id =
            SlaacTimerId::new_deprecate_slaac_address(DummyDeviceId, addr_sub.addr());
        let invalidate_timer_id =
            SlaacTimerId::new_invalidate_slaac_address(DummyDeviceId, addr_sub.addr());

        // Generate a new SLAAC address.
        let ndp_pl = NonZeroNdpLifetime::from_u32_with_infinite(orig_pl_secs);
        let ndp_vl = NonZeroNdpLifetime::from_u32_with_infinite(orig_vl_secs);
        SlaacHandler::apply_slaac_update(
            &mut sync_ctx,
            &mut non_sync_ctx,
            DummyDeviceId,
            SUBNET,
            ndp_pl,
            ndp_vl,
        );
        let address_created_deprecated = ndp_pl.is_none();
        let now = non_sync_ctx.now();
        let mut expected_timers = Vec::new();
        let valid_until = match ndp_vl.expect("this test expects to create an address") {
            NonZeroNdpLifetime::Finite(d) => {
                let valid_until = now + d.get();
                expected_timers.push((invalidate_timer_id, valid_until));
                Lifetime::Finite(valid_until)
            }
            NonZeroNdpLifetime::Infinite => Lifetime::Infinite,
        };
        match ndp_pl {
            None | Some(NonZeroNdpLifetime::Infinite) => {}
            Some(NonZeroNdpLifetime::Finite(d)) => {
                expected_timers.push((deprecate_timer_id, now + d.get()))
            }
        }
        let entry = SlaacAddressEntry {
            addr_sub,
            config: SlaacConfig::Static { valid_until },
            deprecated: address_created_deprecated,
        };
        assert_eq!(sync_ctx.iter_slaac_addrs(DummyDeviceId).collect::<Vec<_>>(), [entry],);
        non_sync_ctx.timer_ctx().assert_timers_installed(expected_timers);

        // Refresh timers.
        let ndp_pl = NonZeroNdpLifetime::from_u32_with_infinite(new_pl_secs);
        SlaacHandler::apply_slaac_update(
            &mut sync_ctx,
            &mut non_sync_ctx,
            DummyDeviceId,
            SUBNET,
            ndp_pl,
            NonZeroNdpLifetime::from_u32_with_infinite(new_vl_secs),
        );
        let mut expected_timers = Vec::new();
        let valid_until = match NonZeroNdpLifetime::from_u32_with_infinite(effective_new_vl_secs)
            .expect("this test expects to keep the address")
        {
            NonZeroNdpLifetime::Finite(d) => {
                let valid_until = now + d.get();
                expected_timers.push((invalidate_timer_id, valid_until));
                Lifetime::Finite(valid_until)
            }
            NonZeroNdpLifetime::Infinite => Lifetime::Infinite,
        };
        match ndp_pl {
            None | Some(NonZeroNdpLifetime::Infinite) => {}
            Some(NonZeroNdpLifetime::Finite(d)) => {
                expected_timers.push((deprecate_timer_id, now + d.get()))
            }
        }
        let entry = SlaacAddressEntry {
            config: SlaacConfig::Static { valid_until },
            deprecated: ndp_pl.is_none(),
            ..entry
        };
        assert_eq!(sync_ctx.iter_slaac_addrs(DummyDeviceId).collect::<Vec<_>>(), [entry],);
        non_sync_ctx.timer_ctx().assert_timers_installed(expected_timers);
    }

    const SECRET_KEY: [u8; STABLE_IID_SECRET_KEY_BYTES] = [1; STABLE_IID_SECRET_KEY_BYTES];

    const ONE_HOUR: NonZeroDuration = NonZeroDuration::from_nonzero_secs(
        const_unwrap::const_unwrap_option(NonZeroU64::new(ONE_HOUR_AS_SECS as u64)),
    );

    struct DontGenerateTemporaryAddressTest {
        preferred_lifetime_config: NonZeroDuration,
        preferred_lifetime_secs: u32,
        valid_lifetime_secs: u32,
        temp_idgen_retries: u8,
        dad_transmits: u8,
        retrans_timer: Duration,
        enable: bool,
    }

    impl DontGenerateTemporaryAddressTest {
        fn with_pl_less_than_regen_advance(
            dad_transmits: u8,
            retrans_timer: Duration,
            temp_idgen_retries: u8,
        ) -> Self {
            DontGenerateTemporaryAddressTest {
                preferred_lifetime_config: ONE_HOUR,
                preferred_lifetime_secs: u32::try_from(
                    (MIN_REGEN_ADVANCE.get()
                        + (u32::from(temp_idgen_retries)
                            * u32::from(dad_transmits)
                            * retrans_timer))
                        .as_secs(),
                )
                .unwrap()
                    - 1,
                valid_lifetime_secs: TWO_HOURS_AS_SECS,
                temp_idgen_retries,
                dad_transmits,
                retrans_timer,
                enable: true,
            }
        }
    }

    #[test_case(DontGenerateTemporaryAddressTest {
        preferred_lifetime_config: ONE_HOUR,
        preferred_lifetime_secs: ONE_HOUR_AS_SECS,
        valid_lifetime_secs: TWO_HOURS_AS_SECS,
        temp_idgen_retries: 0,
        dad_transmits: 0,
        retrans_timer: DEFAULT_RETRANS_TIMER,
        enable: false,
    }; "disabled")]
    #[test_case(DontGenerateTemporaryAddressTest{
        preferred_lifetime_config: ONE_HOUR,
        preferred_lifetime_secs: 0,
        valid_lifetime_secs: 0,
        temp_idgen_retries: 0,
        dad_transmits: 0,
        retrans_timer: DEFAULT_RETRANS_TIMER,
        enable: true,
    }; "zero lifetimes")]
    #[test_case(DontGenerateTemporaryAddressTest {
        preferred_lifetime_config: ONE_HOUR,
        preferred_lifetime_secs: TWO_HOURS_AS_SECS,
        valid_lifetime_secs: ONE_HOUR_AS_SECS,
        temp_idgen_retries: 0,
        dad_transmits: 0,
        retrans_timer: DEFAULT_RETRANS_TIMER,
        enable: true,
    }; "preferred larger than valid")]
    #[test_case(DontGenerateTemporaryAddressTest {
        preferred_lifetime_config: ONE_HOUR,
        preferred_lifetime_secs: 0,
        valid_lifetime_secs: TWO_HOURS_AS_SECS,
        temp_idgen_retries: 0,
        dad_transmits: 0,
        retrans_timer: DEFAULT_RETRANS_TIMER,
        enable: true,
    }; "not preferred")]
    #[test_case(DontGenerateTemporaryAddressTest::with_pl_less_than_regen_advance(
        0 /* dad_transmits */,
        DEFAULT_RETRANS_TIMER /* retrans_timer */,
        0 /* temp_idgen_retries */,
    ); "preferred lifetime less than than regen advance with no DAD transmits")]
    #[test_case(DontGenerateTemporaryAddressTest::with_pl_less_than_regen_advance(
        1 /* dad_transmits */,
        DEFAULT_RETRANS_TIMER /* retrans_timer */,
        0 /* temp_idgen_retries */,
    ); "preferred lifetime less than than regen advance with DAD transmits")]
    #[test_case(DontGenerateTemporaryAddressTest::with_pl_less_than_regen_advance(
        1 /* dad_transmits */,
        DEFAULT_RETRANS_TIMER /* retrans_timer */,
        1 /* temp_idgen_retries */,
    ); "preferred lifetime less than than regen advance with DAD transmits and retries")]
    #[test_case(DontGenerateTemporaryAddressTest::with_pl_less_than_regen_advance(
        2 /* dad_transmits */,
        DEFAULT_RETRANS_TIMER + Duration::from_secs(1) /* retrans_timer */,
        3 /* temp_idgen_retries */,
    ); "preferred lifetime less than than regen advance with multiple DAD transmits and multiple retries")]
    #[test_case(DontGenerateTemporaryAddressTest {
        preferred_lifetime_config: MIN_REGEN_ADVANCE,
        preferred_lifetime_secs: ONE_HOUR_AS_SECS,
        valid_lifetime_secs: TWO_HOURS_AS_SECS,
        temp_idgen_retries: 1,
        dad_transmits: 1,
        retrans_timer: DEFAULT_RETRANS_TIMER,
        enable: true,
    }; "configured preferred lifetime less than regen advance")]
    fn dont_generate_temporary_address(
        DontGenerateTemporaryAddressTest {
            preferred_lifetime_config,
            preferred_lifetime_secs,
            valid_lifetime_secs,
            temp_idgen_retries,
            dad_transmits,
            retrans_timer,
            enable,
        }: DontGenerateTemporaryAddressTest,
    ) {
        let DummyCtx { mut sync_ctx, mut non_sync_ctx } =
            DummyCtx::with_sync_ctx(MockCtx::with_state(MockSlaacContext {
                config: SlaacConfiguration {
                    temporary_address_configuration: enable.then(|| {
                        TemporarySlaacAddressConfiguration {
                            temp_valid_lifetime: NonZeroDuration::new(Duration::from_secs(
                                ONE_HOUR_AS_SECS.into(),
                            ))
                            .unwrap(),
                            temp_preferred_lifetime: preferred_lifetime_config,
                            temp_idgen_retries,
                            secret_key: SECRET_KEY,
                        }
                    }),
                    ..Default::default()
                },
                dad_transmits: NonZeroU8::new(dad_transmits),
                retrans_timer,
                iid: IID,
                slaac_addrs: Default::default(),
                non_slaac_addr: None,
            }));

        SlaacHandler::apply_slaac_update(
            &mut sync_ctx,
            &mut non_sync_ctx,
            DummyDeviceId,
            SUBNET,
            NonZeroNdpLifetime::from_u32_with_infinite(preferred_lifetime_secs),
            NonZeroNdpLifetime::from_u32_with_infinite(valid_lifetime_secs),
        );
        assert_empty(sync_ctx.iter_slaac_addrs(DummyDeviceId));
        non_sync_ctx.timer_ctx().assert_no_timers_installed();
    }

    struct GenerateTemporaryAddressTest {
        pl_config: u32,
        vl_config: u32,
        dad_transmits: u8,
        retrans_timer: Duration,
        temp_idgen_retries: u8,
        pl_ra: u32,
        vl_ra: u32,
        expected_pl_addr: u32,
        expected_vl_addr: u32,
    }
    #[test_case(GenerateTemporaryAddressTest{
        pl_config: ONE_HOUR_AS_SECS,
        vl_config: ONE_HOUR_AS_SECS,
        dad_transmits: 0,
        retrans_timer: DEFAULT_RETRANS_TIMER,
        temp_idgen_retries: 0,
        pl_ra: ONE_HOUR_AS_SECS,
        vl_ra: ONE_HOUR_AS_SECS,
        expected_pl_addr: ONE_HOUR_AS_SECS,
        expected_vl_addr: ONE_HOUR_AS_SECS,
    }; "config and prefix same lifetimes")]
    #[test_case(GenerateTemporaryAddressTest{
        pl_config: ONE_HOUR_AS_SECS,
        vl_config: TWO_HOURS_AS_SECS,
        dad_transmits: 0,
        retrans_timer: DEFAULT_RETRANS_TIMER,
        temp_idgen_retries: 0,
        pl_ra: THREE_HOURS_AS_SECS,
        vl_ra: THREE_HOURS_AS_SECS,
        expected_pl_addr: ONE_HOUR_AS_SECS,
        expected_vl_addr: TWO_HOURS_AS_SECS,
    }; "config smaller than prefix lifetimes")]
    #[test_case(GenerateTemporaryAddressTest{
        pl_config: TWO_HOURS_AS_SECS,
        vl_config: THREE_HOURS_AS_SECS,
        dad_transmits: 0,
        retrans_timer: DEFAULT_RETRANS_TIMER,
        temp_idgen_retries: 0,
        pl_ra: ONE_HOUR_AS_SECS,
        vl_ra: TWO_HOURS_AS_SECS,
        expected_pl_addr: ONE_HOUR_AS_SECS,
        expected_vl_addr: TWO_HOURS_AS_SECS,
    }; "config larger than prefix lifetimes")]
    #[test_case(GenerateTemporaryAddressTest{
        pl_config: TWO_HOURS_AS_SECS,
        vl_config: THREE_HOURS_AS_SECS,
        dad_transmits: 0,
        retrans_timer: DEFAULT_RETRANS_TIMER,
        temp_idgen_retries: 0,
        pl_ra: INFINITE_LIFETIME,
        vl_ra: INFINITE_LIFETIME,
        expected_pl_addr: TWO_HOURS_AS_SECS,
        expected_vl_addr: THREE_HOURS_AS_SECS,
    }; "prefix with infinite lifetimes")]
    #[test_case(GenerateTemporaryAddressTest{
        pl_config: TWO_HOURS_AS_SECS,
        vl_config: THREE_HOURS_AS_SECS,
        dad_transmits: 1,
        retrans_timer: DEFAULT_RETRANS_TIMER,
        temp_idgen_retries: 0,
        pl_ra: INFINITE_LIFETIME,
        vl_ra: INFINITE_LIFETIME,
        expected_pl_addr: TWO_HOURS_AS_SECS,
        expected_vl_addr: THREE_HOURS_AS_SECS,
    }; "generate_with_dad_enabled")]
    #[test_case(GenerateTemporaryAddressTest{
        pl_config: TWO_HOURS_AS_SECS,
        vl_config: THREE_HOURS_AS_SECS,
        dad_transmits: 2,
        retrans_timer: Duration::from_secs(5),
        temp_idgen_retries: 3,
        pl_ra: INFINITE_LIFETIME,
        vl_ra: INFINITE_LIFETIME,
        expected_pl_addr: TWO_HOURS_AS_SECS,
        expected_vl_addr: THREE_HOURS_AS_SECS,
    }; "generate_with_dad_enabled_and_retries")]
    #[test_case(GenerateTemporaryAddressTest{
        pl_config: TWO_HOURS_AS_SECS,
        vl_config: THREE_HOURS_AS_SECS,
        dad_transmits: 1,
        retrans_timer: Duration::from_secs(10),
        temp_idgen_retries: 0,
        pl_ra: INFINITE_LIFETIME,
        vl_ra: INFINITE_LIFETIME,
        expected_pl_addr: TWO_HOURS_AS_SECS,
        expected_vl_addr: THREE_HOURS_AS_SECS,
    }; "generate_with_dad_enabled_but_no_retries")]
    fn generate_temporary_address(
        GenerateTemporaryAddressTest {
            pl_config,
            vl_config,
            dad_transmits,
            retrans_timer,
            temp_idgen_retries,
            pl_ra,
            vl_ra,
            expected_pl_addr,
            expected_vl_addr,
        }: GenerateTemporaryAddressTest,
    ) {
        let pl_config = Duration::from_secs(pl_config.into());
        let regen_advance = regen_advance(temp_idgen_retries, retrans_timer, dad_transmits);

        let DummyCtx { mut sync_ctx, mut non_sync_ctx } =
            DummyCtx::with_sync_ctx(MockCtx::with_state(MockSlaacContext {
                config: SlaacConfiguration {
                    temporary_address_configuration: Some(TemporarySlaacAddressConfiguration {
                        temp_valid_lifetime: NonZeroDuration::new(Duration::from_secs(
                            vl_config.into(),
                        ))
                        .unwrap(),
                        temp_preferred_lifetime: NonZeroDuration::new(pl_config).unwrap(),
                        temp_idgen_retries,
                        secret_key: SECRET_KEY,
                    }),
                    ..Default::default()
                },
                dad_transmits: NonZeroU8::new(dad_transmits),
                retrans_timer,
                iid: IID,
                slaac_addrs: Default::default(),
                non_slaac_addr: None,
            }));
        let sync_ctx = &mut sync_ctx;

        let mut dup_rng = non_sync_ctx.rng().clone();

        struct AddrProps {
            desync_factor: Duration,
            valid_until: DummyInstant,
            preferred_until: DummyInstant,
            entry: SlaacAddressEntry<DummyInstant>,
            deprecate_timer_id: SlaacTimerId<DummyDeviceId>,
            invalidate_timer_id: SlaacTimerId<DummyDeviceId>,
            regenerate_timer_id: SlaacTimerId<DummyDeviceId>,
        }

        let addr_props = |rng: &mut FakeCryptoRng<_>,
                          creation_time,
                          config_greater_than_ra_desync_factor_offset| {
            let valid_until = creation_time + Duration::from_secs(expected_vl_addr.into());
            let addr_sub =
                generate_global_temporary_address(&SUBNET, &IID, rng.next_u64(), &SECRET_KEY);
            let desync_factor =
                desync_factor(rng, NonZeroDuration::new(pl_config).unwrap(), regen_advance)
                    .unwrap();

            AddrProps {
                desync_factor,
                valid_until,
                preferred_until: {
                    let d = creation_time + Duration::from_secs(expected_pl_addr.into());
                    if pl_config.as_secs() > pl_ra.into() {
                        d + config_greater_than_ra_desync_factor_offset
                    } else {
                        d - desync_factor
                    }
                },
                entry: SlaacAddressEntry {
                    addr_sub,
                    config: SlaacConfig::Temporary(TemporarySlaacConfig {
                        valid_until,
                        desync_factor,
                        creation_time,
                        dad_counter: 0,
                    }),
                    deprecated: false,
                },
                deprecate_timer_id: SlaacTimerId::new_deprecate_slaac_address(
                    DummyDeviceId,
                    addr_sub.addr(),
                ),
                invalidate_timer_id: SlaacTimerId::new_invalidate_slaac_address(
                    DummyDeviceId,
                    addr_sub.addr(),
                ),
                regenerate_timer_id: SlaacTimerId::new_regenerate_temporary_slaac_address(
                    DummyDeviceId,
                    addr_sub,
                ),
            }
        };

        // Generate the first temporary SLAAC address.
        SlaacHandler::apply_slaac_update(
            sync_ctx,
            &mut non_sync_ctx,
            DummyDeviceId,
            SUBNET,
            NonZeroNdpLifetime::from_u32_with_infinite(pl_ra),
            NonZeroNdpLifetime::from_u32_with_infinite(vl_ra),
        );
        let AddrProps {
            desync_factor: first_desync_factor,
            valid_until: first_valid_until,
            preferred_until: first_preferred_until,
            entry: first_entry,
            deprecate_timer_id: first_deprecate_timer_id,
            invalidate_timer_id: first_invalidate_timer_id,
            regenerate_timer_id: first_regenerate_timer_id,
        } = addr_props(&mut dup_rng, non_sync_ctx.now(), Duration::ZERO);
        assert_eq!(sync_ctx.iter_slaac_addrs(DummyDeviceId).collect::<Vec<_>>(), [first_entry]);
        non_sync_ctx.timer_ctx().assert_timers_installed([
            (first_deprecate_timer_id, first_preferred_until),
            (first_invalidate_timer_id, first_valid_until),
            (first_regenerate_timer_id, first_preferred_until - regen_advance.get()),
        ]);

        // Trigger the regenerate timer to generate the second temporary SLAAC
        // address.
        assert_eq!(
            non_sync_ctx.trigger_next_timer(sync_ctx, TimerHandler::handle_timer),
            Some(first_regenerate_timer_id),
        );
        let AddrProps {
            desync_factor: second_desync_factor,
            valid_until: second_valid_until,
            preferred_until: second_preferred_until,
            entry: second_entry,
            deprecate_timer_id: second_deprecate_timer_id,
            invalidate_timer_id: second_invalidate_timer_id,
            regenerate_timer_id: second_regenerate_timer_id,
        } = addr_props(&mut dup_rng, non_sync_ctx.now(), first_desync_factor);
        assert_eq!(
            sync_ctx.iter_slaac_addrs(DummyDeviceId).collect::<Vec<_>>(),
            [first_entry, second_entry]
        );
        let second_regen_at = second_preferred_until - regen_advance.get();
        non_sync_ctx.timer_ctx().assert_timers_installed([
            (first_deprecate_timer_id, first_preferred_until),
            (first_invalidate_timer_id, first_valid_until),
            (second_deprecate_timer_id, second_preferred_until),
            (second_invalidate_timer_id, second_valid_until),
            (second_regenerate_timer_id, second_regen_at),
        ]);

        // Deprecate first address.
        assert_eq!(
            non_sync_ctx.trigger_next_timer(sync_ctx, TimerHandler::handle_timer),
            Some(first_deprecate_timer_id),
        );
        let first_entry = SlaacAddressEntry { deprecated: true, ..first_entry };
        assert_eq!(
            sync_ctx.iter_slaac_addrs(DummyDeviceId).collect::<Vec<_>>(),
            [first_entry, second_entry]
        );
        non_sync_ctx.timer_ctx().assert_timers_installed([
            (first_invalidate_timer_id, first_valid_until),
            (second_deprecate_timer_id, second_preferred_until),
            (second_invalidate_timer_id, second_valid_until),
            (second_regenerate_timer_id, second_regen_at),
        ]);

        let third_created_at = {
            let expected_timer_order = if first_valid_until > second_regen_at {
                [second_regenerate_timer_id, second_deprecate_timer_id, first_invalidate_timer_id]
            } else {
                [first_invalidate_timer_id, second_regenerate_timer_id, second_deprecate_timer_id]
            };

            let mut third_created_at = None;
            for timer_id in expected_timer_order.iter() {
                let timer_id = *timer_id;

                assert_eq!(
                    non_sync_ctx.trigger_next_timer(sync_ctx, TimerHandler::handle_timer),
                    Some(timer_id),
                );

                if timer_id == second_regenerate_timer_id {
                    assert_eq!(third_created_at, None);
                    third_created_at = Some(non_sync_ctx.now());
                }
            }

            third_created_at.unwrap()
        };

        // Make sure we regenerated the third address, deprecated the second and
        // invalidated the first.
        let AddrProps {
            desync_factor: _,
            valid_until: third_valid_until,
            preferred_until: third_preferred_until,
            entry: third_entry,
            deprecate_timer_id: third_deprecate_timer_id,
            invalidate_timer_id: third_invalidate_timer_id,
            regenerate_timer_id: third_regenerate_timer_id,
        } = addr_props(&mut dup_rng, third_created_at, first_desync_factor + second_desync_factor);
        let second_entry = SlaacAddressEntry { deprecated: true, ..second_entry };
        assert_eq!(
            sync_ctx.iter_slaac_addrs(DummyDeviceId).collect::<Vec<_>>(),
            [second_entry, third_entry]
        );
        non_sync_ctx.timer_ctx().assert_some_timers_installed([
            (second_invalidate_timer_id, second_valid_until),
            (third_deprecate_timer_id, third_preferred_until),
            (third_invalidate_timer_id, third_valid_until),
            (third_regenerate_timer_id, third_preferred_until - regen_advance.get()),
        ]);
    }

    fn build_slaac_ra_packet(
        src_ip: Ipv6Addr,
        dst_ip: Ipv6Addr,
        prefix: Ipv6Addr,
        prefix_length: u8,
        preferred_lifetime_secs: u32,
        valid_lifetime_secs: u32,
    ) -> Buf<Vec<u8>> {
        let p = PrefixInformation::new(
            prefix_length,
            false, /* on_link_flag */
            true,  /* autonomous_address_configuration_flag */
            valid_lifetime_secs,
            preferred_lifetime_secs,
            prefix,
        );
        let options = &[NdpOptionBuilder::PrefixInformation(p)];
        OptionSequenceBuilder::new(options.iter())
            .into_serializer()
            .encapsulate(IcmpPacketBuilder::<Ipv6, &[u8], _>::new(
                src_ip,
                dst_ip,
                IcmpUnusedCode,
                RouterAdvertisement::new(0, false, false, 0, 0, 0),
            ))
            .encapsulate(Ipv6PacketBuilder::new(
                src_ip,
                dst_ip,
                REQUIRED_NDP_IP_PACKET_HOP_LIMIT,
                Ipv6Proto::Icmpv6,
            ))
            .serialize_vec_outer()
            .unwrap()
            .unwrap_b()
    }

    #[test]
    fn integration_remove_all_addresses_on_ipv6_disable() {
        let DummyEventDispatcherConfig {
            local_mac,
            remote_mac,
            local_ip: _,
            remote_ip: _,
            subnet: _,
        } = Ipv6::DUMMY_CONFIG;

        const ONE_HOUR: NonZeroDuration = NonZeroDuration::from_nonzero_secs(
            const_unwrap::const_unwrap_option(NonZeroU64::new(ONE_HOUR_AS_SECS as u64)),
        );
        const TWO_HOURS: NonZeroDuration = NonZeroDuration::from_nonzero_secs(
            const_unwrap::const_unwrap_option(NonZeroU64::new(TWO_HOURS_AS_SECS as u64)),
        );

        let Ctx { mut sync_ctx, mut non_sync_ctx } = crate::testutil::DummyCtx::default();
        let device_id =
            sync_ctx.state.device.add_ethernet_device(local_mac, Ipv6::MINIMUM_LINK_MTU.into());
        crate::ip::device::update_ipv6_configuration(
            &mut sync_ctx,
            &mut non_sync_ctx,
            device_id,
            |config| {
                config.slaac_config = SlaacConfiguration {
                    enable_stable_addresses: true,
                    temporary_address_configuration: Some(TemporarySlaacAddressConfiguration {
                        temp_valid_lifetime: ONE_HOUR,
                        temp_preferred_lifetime: ONE_HOUR,
                        temp_idgen_retries: 0,
                        secret_key: SECRET_KEY,
                    }),
                };
            },
        );

        let set_ip_enabled = |sync_ctx: &mut crate::testutil::DummySyncCtx,
                              non_sync_ctx: &mut crate::testutil::DummyNonSyncCtx,
                              enabled| {
            crate::ip::device::update_ipv6_configuration(
                sync_ctx,
                non_sync_ctx,
                device_id,
                |config| {
                    config.ip_config.ip_enabled = enabled;
                },
            )
        };
        set_ip_enabled(&mut sync_ctx, &mut non_sync_ctx, true /* enabled */);
        non_sync_ctx.timer_ctx().assert_no_timers_installed();

        // Generate stable and temporary SLAAC addresses.
        receive_ipv6_packet(
            &mut sync_ctx,
            &mut non_sync_ctx,
            device_id,
            FrameDestination::Multicast,
            build_slaac_ra_packet(
                remote_mac.to_ipv6_link_local().addr().get(),
                Ipv6::ALL_NODES_LINK_LOCAL_MULTICAST_ADDRESS.get(),
                SUBNET.network(),
                SUBNET.prefix(),
                u32::try_from(TWO_HOURS.get().as_secs()).unwrap(),
                u32::try_from(TWO_HOURS.get().as_secs()).unwrap(),
            ),
        );

        let stable_addr_sub =
            calculate_addr_sub(SUBNET, local_mac.to_eui64_with_magic(Mac::DEFAULT_EUI_MAGIC));

        let addrs = get_assigned_ipv6_addr_subnets(&sync_ctx, device_id)
            .filter(|a| !a.addr().is_link_local())
            .collect::<Vec<_>>();
        let (stable_addr_sub, temp_addr_sub) = assert_matches!(
            addrs[..],
            [a1, a2] => {
                let a1 = a1.to_unicast();
                let a2 = a2.to_unicast();

                assert_eq!(a1.subnet(), SUBNET);
                assert_eq!(a2.subnet(), SUBNET);
                assert_ne!(a1, a2);

                if a1 == stable_addr_sub {
                    (a1, a2)
                } else {
                    (a2, a1)
                }
            }
        );
        let now = non_sync_ctx.now();
        let stable_addr_lifetime_until = now + TWO_HOURS.get();
        let temp_addr_lifetime_until = now + ONE_HOUR.get();

        // Account for the desync factor:
        //
        // Per RFC 8981 Section 3.8:
        //    MAX_DESYNC_FACTOR
        //       0.4 * TEMP_PREFERRED_LIFETIME.  Upper bound on DESYNC_FACTOR.
        //
        //       |  Rationale: Setting MAX_DESYNC_FACTOR to 0.4
        //       |  TEMP_PREFERRED_LIFETIME results in addresses that have
        //       |  statistically different lifetimes, and a maximum of three
        //       |  concurrent temporary addresses when the default values
        //       |  specified in this section are employed.
        //    DESYNC_FACTOR
        //       A random value within the range 0 - MAX_DESYNC_FACTOR.  It
        //       is computed each time a temporary address is generated, and
        //       is associated with the corresponding address.  It MUST be
        //       smaller than (TEMP_PREFERRED_LIFETIME - REGEN_ADVANCE).
        let temp_addr_preferred_until_end = now + ONE_HOUR.get();
        let temp_addr_preferred_until_start =
            temp_addr_preferred_until_end - ((ONE_HOUR.get() * 3) / 5);
        non_sync_ctx.timer_ctx().assert_some_timers_installed([
            (
                SlaacTimerId::new_invalidate_slaac_address(device_id, stable_addr_sub.addr())
                    .into(),
                stable_addr_lifetime_until.as_dyn(),
            ),
            (
                SlaacTimerId::new_deprecate_slaac_address(device_id, stable_addr_sub.addr()).into(),
                stable_addr_lifetime_until.as_dyn(),
            ),
            (
                SlaacTimerId::new_invalidate_slaac_address(device_id, temp_addr_sub.addr()).into(),
                temp_addr_lifetime_until.as_dyn(),
            ),
            (
                SlaacTimerId::new_deprecate_slaac_address(device_id, temp_addr_sub.addr()).into(),
                (temp_addr_preferred_until_start..temp_addr_preferred_until_end).as_dyn(),
            ),
            (
                SlaacTimerId::new_regenerate_temporary_slaac_address(device_id, temp_addr_sub)
                    .into(),
                (temp_addr_preferred_until_start - MIN_REGEN_ADVANCE.get()
                    ..temp_addr_preferred_until_end - MIN_REGEN_ADVANCE.get())
                    .as_dyn(),
            ),
        ]);

        // Disabling IP should remove all the SLAAC addresses.
        set_ip_enabled(&mut sync_ctx, &mut non_sync_ctx, false /* enabled */);
        let addrs = get_assigned_ipv6_addr_subnets(&sync_ctx, device_id)
            .filter(|a| !a.addr().is_link_local())
            .collect::<Vec<_>>();
        assert_matches!(addrs[..], []);
        non_sync_ctx.timer_ctx().assert_no_timers_installed();
    }
}
