// 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>> + CounterContext
{
}
impl<DeviceId, C: RngContext + TimerContext<SlaacTimerId<DeviceId>> + CounterContext>
    SlaacNonSyncContext<DeviceId> for C
{
}

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

impl<C: SlaacNonSyncContext<SC::DeviceId>, SC: SlaacStateContext<C>> 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.
                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();
    }
}
