// Copyright 2018 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.

//! The device layer.

pub(crate) mod arp;
pub(crate) mod ethernet;
pub(crate) mod ndp;

use std::fmt::{self, Debug, Display, Formatter};
use std::num::NonZeroU8;

use log::{debug, trace};
use net_types::ethernet::Mac;
use net_types::ip::{AddrSubnet, Ip, IpAddress, Ipv4, Ipv4Addr, Ipv6, Ipv6Addr};
use net_types::{LinkLocalAddr, MulticastAddr, SpecifiedAddr, Witness};
use packet::{BufferMut, Serializer};
use specialize_ip_macro::specialize_ip;

use crate::data_structures::{IdMap, IdMapCollectionKey};
use crate::device::ethernet::{EthernetDeviceState, EthernetDeviceStateBuilder};
use crate::{BufferDispatcher, Context, EventDispatcher, StackState};

/// An ID identifying a device.
#[derive(Copy, Clone, Eq, PartialEq, Hash)]
pub struct DeviceId {
    id: usize,
    protocol: DeviceProtocol,
}

impl DeviceId {
    /// Construct a new `DeviceId` for an Ethernet device.
    pub(crate) fn new_ethernet(id: usize) -> DeviceId {
        DeviceId { id, protocol: DeviceProtocol::Ethernet }
    }

    /// Get the protocol-specific ID for this `DeviceId`.
    pub fn id(self) -> usize {
        self.id
    }

    /// Get the protocol for this `DeviceId`.
    pub fn protocol(self) -> DeviceProtocol {
        self.protocol
    }
}

impl Display for DeviceId {
    fn fmt(&self, f: &mut Formatter) -> Result<(), fmt::Error> {
        write!(f, "{}:{}", self.protocol, self.id)
    }
}

impl Debug for DeviceId {
    fn fmt(&self, f: &mut Formatter) -> Result<(), fmt::Error> {
        Display::fmt(self, f)
    }
}

impl IdMapCollectionKey for DeviceId {
    const VARIANT_COUNT: usize = 1;

    fn get_variant(&self) -> usize {
        match self.protocol {
            DeviceProtocol::Ethernet => 0,
        }
    }

    fn get_id(&self) -> usize {
        self.id as usize
    }
}

/// Type of device protocol.
#[derive(Copy, Clone, Eq, PartialEq, Hash)]
pub enum DeviceProtocol {
    Ethernet,
}

impl Display for DeviceProtocol {
    fn fmt(&self, f: &mut Formatter) -> Result<(), fmt::Error> {
        write!(
            f,
            "{}",
            match self {
                DeviceProtocol::Ethernet => "Ethernet",
            }
        )
    }
}

// TODO(joshlf): Does the IP layer ever need to distinguish between broadcast
// and multicast frames?

/// The type of address used as the source address in a device-layer frame:
/// unicast or broadcast.
///
/// `FrameDestination` is used to implement RFC 1122 section 3.2.2 and RFC 4443
/// section 2.4.e, which govern when to avoid sending an ICMP error message for
/// ICMP and ICMPv6 respectively.
#[derive(Copy, Clone, Eq, PartialEq)]
pub(crate) enum FrameDestination {
    /// A unicast address - one which is neither multicast nor broadcast.
    Unicast,
    /// A multicast address; if the addressing scheme supports overlap between
    /// multicast and broadcast, then broadcast addresses should use the
    /// `Broadcast` variant.
    Multicast,
    /// A broadcast address; if the addressing scheme supports overlap between
    /// multicast and broadcast, then broadcast addresses should use the
    /// `Broadcast` variant.
    Broadcast,
}

impl FrameDestination {
    /// Is this `FrameDestination::Multicast`?
    pub(crate) fn is_multicast(self) -> bool {
        self == FrameDestination::Multicast
    }

    /// Is this `FrameDestination::Broadcast`?
    pub(crate) fn is_broadcast(self) -> bool {
        self == FrameDestination::Broadcast
    }
}

/// Builder for a [`DeviceLayerState`].
#[derive(Clone)]
pub struct DeviceStateBuilder {
    /// Default values for NDP's configurations for new interfaces.
    ///
    /// See [`ndp::NdpConfigurations`].
    default_ndp_configs: ndp::NdpConfigurations,
}

impl Default for DeviceStateBuilder {
    fn default() -> Self {
        Self { default_ndp_configs: ndp::NdpConfigurations::default() }
    }
}

impl DeviceStateBuilder {
    /// Set the default values for NDP's configurations for new interfaces.
    ///
    /// See [`ndp::NdpConfigurations`] for more details.
    pub fn set_default_ndp_configs(&mut self, v: ndp::NdpConfigurations) {
        self.default_ndp_configs = v;
    }

    /// Build the [`DeviceLayerState`].
    pub(crate) fn build<D: EventDispatcher>(self) -> DeviceLayerState<D> {
        DeviceLayerState { ethernet: IdMap::new(), default_ndp_configs: self.default_ndp_configs }
    }
}

/// The state associated with the device layer.
pub(crate) struct DeviceLayerState<D: EventDispatcher> {
    ethernet: IdMap<DeviceState<EthernetDeviceState<D>>>,
    default_ndp_configs: ndp::NdpConfigurations,
}

impl<D: EventDispatcher> DeviceLayerState<D> {
    /// Add a new ethernet device to the device layer.
    ///
    /// `add` adds a new `EthernetDeviceState` with the given MAC address and
    /// MTU. The MTU will be taken as a limit on the size of Ethernet payloads -
    /// the Ethernet header is not counted towards the MTU.
    pub(crate) fn add_ethernet_device(&mut self, mac: Mac, mtu: u32) -> DeviceId {
        let mut builder = EthernetDeviceStateBuilder::new(mac, mtu);
        builder.set_ndp_configs(self.default_ndp_configs.clone());
        let mut ethernet_state = DeviceState::new(builder.build());
        let id = self.ethernet.push(ethernet_state);
        debug!("adding Ethernet device with ID {} and MTU {}", id, mtu);
        DeviceId::new_ethernet(id)
    }
}

/// Common state across devices.
#[derive(Default)]
pub(crate) struct CommonDeviceState {
    /// Is the device initialized?
    is_initialized: bool,
}

/// Device state.
///
/// `D` is the device-specific state.
pub(crate) struct DeviceState<D> {
    /// Device-independant state.
    common: CommonDeviceState,

    /// Device-specific state.
    device: D,
}

impl<D> DeviceState<D> {
    /// Create a new `DeviceState` with a device-specific state `device`.
    pub(crate) fn new(device: D) -> Self {
        Self { common: CommonDeviceState::default(), device }
    }

    /// Get a reference to the common (device-independant) state.
    pub(crate) fn common(&self) -> &CommonDeviceState {
        &self.common
    }

    /// Get a mutable reference to the common (device-independant) state.
    pub(crate) fn common_mut(&mut self) -> &mut CommonDeviceState {
        &mut self.common
    }

    /// Get a reference to the inner (device-specific) state.
    pub(crate) fn device(&self) -> &D {
        &self.device
    }

    /// Get a mutable reference to the inner (device-specific) state.
    pub(crate) fn device_mut(&mut self) -> &mut D {
        &mut self.device
    }
}

/// The identifier for timer events in the device layer.
#[derive(Copy, Clone, Eq, PartialEq, Debug, Hash)]
pub(crate) enum DeviceLayerTimerId {
    /// A timer event in the ARP layer with a protocol type of IPv4
    ArpIpv4(arp::ArpTimerId<usize, Ipv4Addr>),
    Ndp(ndp::NdpTimerId),
}

impl From<arp::ArpTimerId<usize, Ipv4Addr>> for DeviceLayerTimerId {
    fn from(id: arp::ArpTimerId<usize, Ipv4Addr>) -> DeviceLayerTimerId {
        DeviceLayerTimerId::ArpIpv4(id)
    }
}

/// The various states an IP address can be on an interface.
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum AddressState {
    /// The address is assigned to an interface and can be considered
    /// bound to it (all packets destined to the address will be
    /// accepted).
    Assigned,

    /// The address is considered unassigned to an interface for normal
    /// operations, but has the intention of being assigned in the future
    /// (e.g. once NDP's Duplicate Address Detection is completed).
    Tentative,
}

impl AddressState {
    /// Is this address assigned?
    pub(crate) fn is_assigned(self) -> bool {
        self == AddressState::Assigned
    }

    /// Is this address tentative?
    pub(crate) fn is_tentative(self) -> bool {
        self == AddressState::Tentative
    }
}

/// Data associated with an IP addressess on an interface.
pub struct AddressEntry<A: IpAddress> {
    addr_sub: AddrSubnet<A>,
    state: AddressState,
}

impl<A: IpAddress> AddressEntry<A> {
    pub(crate) fn new(addr_sub: AddrSubnet<A>, state: AddressState) -> Self {
        Self { addr_sub, state }
    }

    pub(crate) fn addr_sub(&self) -> &AddrSubnet<A> {
        &self.addr_sub
    }

    pub(crate) fn state(&self) -> AddressState {
        self.state
    }

    pub(crate) fn mark_permanent(&mut self) {
        self.state = AddressState::Assigned;
    }
}

/// Possible return values during an erroneous interface address change operation.
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub enum AddressError {
    AlreadyExists,
    NotFound,
}

/// Handle a timer event firing in the device layer.
pub(crate) fn handle_timeout<D: EventDispatcher>(ctx: &mut Context<D>, id: DeviceLayerTimerId) {
    match id {
        DeviceLayerTimerId::ArpIpv4(inner_id) => arp::handle_timer(ctx, inner_id),
        DeviceLayerTimerId::Ndp(inner_id) => ndp::handle_timeout(ctx, inner_id),
    }
}

/// An event dispatcher for the device layer.
///
/// See the `EventDispatcher` trait in the crate root for more details.
pub trait DeviceLayerEventDispatcher<B: BufferMut> {
    /// Send a frame to a device driver.
    ///
    /// If there was an MTU error while attempting to serialize the frame, the
    /// original serializer is returned in the `Err` variant. All other errors
    /// (for example, errors in allocating a buffer) are silently ignored and
    /// reported as success.
    ///
    /// Note, until `device` has been initialized, the netstack promises to not
    /// send any outbound traffic to it. See [`initialize_device`] for more
    /// information.
    fn send_frame<S: Serializer<Buffer = B>>(
        &mut self,
        device: DeviceId,
        frame: S,
    ) -> Result<(), S>;
}

/// Is `device` initialized?
pub(crate) fn is_device_initialized<D: EventDispatcher>(
    state: &StackState<D>,
    device: DeviceId,
) -> bool {
    get_common_device_state(state, device).is_initialized
}

/// Initialize a device.
///
/// `initialize_device` will start soliciting IPv6 routers on the link if `device` is configured to
/// be a host. If it is configured to be an advertising interface, it will start sending periodic
/// router advertisements.
///
/// `initialize_device` MUST be called after adding the device to the netstack. A device MUST NOT
/// be used until it has been initialized.
///
/// This initialize step is kept separated from the device creation/allocation step so that
/// implementations have a chance to do some work (such as updating implementation specific IDs or
/// state, configure the device or driver, etc.) before the device is actually initialized and used
/// by this netstack.
///
/// See [`StackState::add_ethernet_device`] for information about adding ethernet devices.
///
/// # Panics
///
/// Panics if `device` is already initialized.
pub fn initialize_device<D: EventDispatcher>(ctx: &mut Context<D>, device: DeviceId) {
    let state = get_common_device_state_mut(ctx.state_mut(), device);

    // `device` must not already be initialized.
    assert!(!state.is_initialized);

    state.is_initialized = true;

    // All nodes should join the all-nodes multicast group.
    join_ip_multicast(ctx, device, MulticastAddr::new(Ipv6::ALL_NODES_LINK_LOCAL_ADDRESS).unwrap());

    if self::is_router_device::<_, Ipv6>(ctx, device) {
        // If the device is operating as a router, and it is configured to be an advertising
        // interface, start sending periodic router advertisements.
        if get_ndp_configurations(ctx, device)
            .get_router_configurations()
            .get_should_send_advertisements()
        {
            match device.protocol {
                DeviceProtocol::Ethernet => ndp::start_advertising_interface::<
                    _,
                    ethernet::EthernetNdpDevice,
                >(ctx, device.id),
            }
        }
    } else {
        // RFC 4861 section 6.3.7, it implies only a host sends router solicitation messages.
        match device.protocol {
            DeviceProtocol::Ethernet => {
                ndp::start_soliciting_routers::<_, ethernet::EthernetNdpDevice>(ctx, device.id)
            }
        }
    }
}

/// Remove a device from the device layer.
///
/// This function returns frames for the bindings to send if the shutdown is graceful - they can be
/// safely ignored otherwise.
///
/// # Panics
///
/// Panics if `device` does not refer to an existing device.
pub fn remove_device<D: EventDispatcher>(
    ctx: &mut Context<D>,
    device: DeviceId,
) -> Option<Vec<usize>> {
    match device.protocol {
        DeviceProtocol::Ethernet => {
            // TODO(rheacock): Generate any final frames to send here.
            crate::device::ethernet::deinitialize(ctx, device.id);
            ctx.state_mut()
                .device
                .ethernet
                .remove(device.id)
                .unwrap_or_else(|| panic!("no such Ethernet device: {}", device.id));
            debug!("removing Ethernet device with ID {}", device.id);
            None
        }
    }
}

/// Send an IP packet in a device layer frame.
///
/// `send_ip_frame` accepts a device ID, a local IP address, and a
/// `SerializationRequest`. It computes the routing information and serializes
/// the request in a new device layer frame and sends it.
///
/// # Panics
///
/// Panics if `device` is not initialized.
pub(crate) fn send_ip_frame<B: BufferMut, D: BufferDispatcher<B>, A, S>(
    ctx: &mut Context<D>,
    device: DeviceId,
    local_addr: SpecifiedAddr<A>,
    body: S,
) -> Result<(), S>
where
    A: IpAddress,
    S: Serializer<Buffer = B>,
{
    // `device` must be initialized.
    assert!(is_device_initialized(ctx.state(), device));

    match device.protocol {
        DeviceProtocol::Ethernet => self::ethernet::send_ip_frame(ctx, device.id, local_addr, body),
    }
}

/// Receive a device layer frame from the network.
///
/// # Panics
///
/// Panics if `device` is not initialized.
pub fn receive_frame<B: BufferMut, D: BufferDispatcher<B>>(
    ctx: &mut Context<D>,
    device: DeviceId,
    buffer: B,
) {
    // `device` must be initialized.
    assert!(is_device_initialized(ctx.state(), device));

    match device.protocol {
        DeviceProtocol::Ethernet => self::ethernet::receive_frame(ctx, device.id, buffer),
    }
}

/// Set the promiscuous mode flag on `device`.
pub(crate) fn set_promiscuous_mode<D: EventDispatcher>(
    ctx: &mut Context<D>,
    device: DeviceId,
    enabled: bool,
) {
    match device.protocol {
        DeviceProtocol::Ethernet => self::ethernet::set_promiscuous_mode(ctx, device.id, enabled),
    }
}

/// Get a single IP address and subnet for a device.
///
/// Note, tentative IP addresses (addresses which are not yet fully bound to a
/// device) will not be returned by `get_ip_addr`.
pub(crate) fn get_ip_addr_subnet<D: EventDispatcher, A: IpAddress>(
    state: &StackState<D>,
    device: DeviceId,
) -> Option<AddrSubnet<A>> {
    match device.protocol {
        DeviceProtocol::Ethernet => self::ethernet::get_ip_addr_subnet(state, device.id),
    }
}

/// Get the IP addresses and associated subnets for a device.
///
/// Note, tentative IP addresses (addresses which are not yet fully bound to a
/// device) will not be returned by `get_ip_addr_subnets`.
///
/// Returns an [`Iterator`] of `AddrSubnet<A>`.
///
/// See [`Tentative`] and [`AddrSubnet`] for more information.
pub fn get_ip_addr_subnets<'a, D: EventDispatcher, A: IpAddress>(
    state: &'a StackState<D>,
    device: DeviceId,
) -> impl 'a + Iterator<Item = AddrSubnet<A>> {
    match device.protocol {
        DeviceProtocol::Ethernet => self::ethernet::get_ip_addr_subnets(state, device.id),
    }
}

/// Get the IP addresses and associated subnets for a device, including tentative
/// address.
///
/// Returns an [`Iterator`] of `Tentative<AddrSubnet<A>>`.
///
/// See [`Tentative`] and [`AddrSubnet`] for more information.
pub fn get_ip_addr_subnets_with_tentative<'a, D: EventDispatcher, A: IpAddress>(
    state: &'a StackState<D>,
    device: DeviceId,
) -> impl 'a + Iterator<Item = Tentative<AddrSubnet<A>>> {
    match device.protocol {
        DeviceProtocol::Ethernet => {
            self::ethernet::get_ip_addr_subnets_with_tentative(state, device.id)
        }
    }
}

/// Get the state of an address on device.
///
/// Returns `None` if `addr` is not associated with `device`.
pub fn get_ip_addr_state<D: EventDispatcher, A: IpAddress>(
    state: &StackState<D>,
    device: DeviceId,
    addr: &SpecifiedAddr<A>,
) -> Option<AddressState> {
    match device.protocol {
        DeviceProtocol::Ethernet => self::ethernet::get_ip_addr_state(state, device.id, addr),
    }
}

/// Adds an IP address and associated subnet to this device.
///
/// # Panics
///
/// Panics if `device` is not initialized.
pub fn add_ip_addr_subnet<D: EventDispatcher, A: IpAddress>(
    ctx: &mut Context<D>,
    device: DeviceId,
    addr_sub: AddrSubnet<A>,
) -> Result<(), AddressError> {
    // `device` must be initialized.
    assert!(is_device_initialized(ctx.state(), device));

    trace!("add_ip_addr_subnet: adding addr {:?} to device {:?}", addr_sub, device);

    match device.protocol {
        DeviceProtocol::Ethernet => self::ethernet::add_ip_addr_subnet(ctx, device.id, addr_sub),
    }
}

/// Removes an IP address and associated subnet to this device.
///
/// # Panics
///
/// Panics if `device` is not initialized.
pub fn del_ip_addr<D: EventDispatcher, A: IpAddress>(
    ctx: &mut Context<D>,
    device: DeviceId,
    addr: &SpecifiedAddr<A>,
) -> Result<(), AddressError> {
    // `device` must be initialized.
    assert!(is_device_initialized(ctx.state(), device));

    trace!("del_ip_addr: removing addr {:?} from device {:?}", addr, device);

    match device.protocol {
        DeviceProtocol::Ethernet => self::ethernet::del_ip_addr(ctx, device.id, addr),
    }
}

/// Add `device` to a multicast group `multicast_addr`.
///
/// If `device` is already in the multicast group `multicast_addr`,
/// `join_ip_multicast` does nothing.
///
/// # Panics
///
/// Panics if `device` is not initialized.
pub(crate) fn join_ip_multicast<D: EventDispatcher, A: IpAddress>(
    ctx: &mut Context<D>,
    device: DeviceId,
    multicast_addr: MulticastAddr<A>,
) {
    // `device` must be initialized.
    assert!(is_device_initialized(ctx.state(), device));

    trace!("join_ip_multicast: device {:?} joining multicast {:?}", device, multicast_addr);

    match device.protocol {
        DeviceProtocol::Ethernet => {
            self::ethernet::join_ip_multicast(ctx, device.id, multicast_addr)
        }
    }
}

/// Remove `device` from a multicast group `multicast_addr`.
///
/// If `device` is not in the multicast group `multicast_addr`,
/// `leave_ip_multicast` does nothing.
///
/// # Panics
///
/// Panics if `device` is not initialized.
pub(crate) fn leave_ip_multicast<D: EventDispatcher, A: IpAddress>(
    ctx: &mut Context<D>,
    device: DeviceId,
    multicast_addr: MulticastAddr<A>,
) {
    // `device` must be initialized.
    assert!(is_device_initialized(ctx.state(), device));

    trace!("join_ip_multicast: device {:?} leaving multicast {:?}", device, multicast_addr);

    match device.protocol {
        DeviceProtocol::Ethernet => {
            self::ethernet::leave_ip_multicast(ctx, device.id, multicast_addr)
        }
    }
}

/// Is `device` part of the IP multicast group `multicast_addr`.
pub(crate) fn is_in_ip_multicast<D: EventDispatcher, A: IpAddress>(
    ctx: &Context<D>,
    device: DeviceId,
    multicast_addr: MulticastAddr<A>,
) -> bool {
    match device.protocol {
        DeviceProtocol::Ethernet => {
            self::ethernet::is_in_ip_multicast(ctx, device.id, multicast_addr)
        }
    }
}

/// Get the MTU associated with this device.
pub(crate) fn get_mtu<D: EventDispatcher>(state: &StackState<D>, device: DeviceId) -> u32 {
    match device.protocol {
        DeviceProtocol::Ethernet => self::ethernet::get_mtu(state, device.id),
    }
}

/// Get the hop limit for new IPv6 packets that will be sent out from `device`.
pub(crate) fn get_ipv6_hop_limit<D: EventDispatcher>(
    ctx: &Context<D>,
    device: DeviceId,
) -> NonZeroU8 {
    match device.protocol {
        DeviceProtocol::Ethernet => self::ethernet::get_ipv6_hop_limit(ctx, device.id),
    }
}

/// Gets the IPv6 link-local address associated with this device.
// TODO(brunodalbo) when our device model allows for multiple IPs we can have
// a single function go get all the IP addresses associated with a device, which
// would be cleaner and remove the need for this function.
pub fn get_ipv6_link_local_addr<D: EventDispatcher>(
    ctx: &Context<D>,
    device: DeviceId,
) -> Option<LinkLocalAddr<Ipv6Addr>> {
    match device.protocol {
        DeviceProtocol::Ethernet => self::ethernet::get_ipv6_link_local_addr(ctx, device.id),
    }
}

/// Determine if an IP Address is considered tentative on a device.
///
/// Returns `true` if the address is tentative on a device; `false` otherwise.
/// Note, if the `addr` is not assigned to `device` but is considered tentative
/// on another device, `is_addr_tentative_on_device` will return `false`.
pub(crate) fn is_addr_tentative_on_device<D: EventDispatcher, A: IpAddress>(
    state: &StackState<D>,
    addr: SpecifiedAddr<A>,
    device: DeviceId,
) -> bool {
    get_ip_addr_subnets_with_tentative::<_, A>(state, device)
        .any(|x| (x.inner().addr() == addr) && x.is_tentative())
}

/// Get a reference to the common device state for a `device`.
fn get_common_device_state<D: EventDispatcher>(
    state: &StackState<D>,
    device: DeviceId,
) -> &CommonDeviceState {
    match device.protocol {
        DeviceProtocol::Ethernet => state
            .device
            .ethernet
            .get(device.id)
            .unwrap_or_else(|| panic!("no such Ethernet device: {}", device.id))
            .common(),
    }
}

/// Get a mutable reference to the common device state for a `device`.
fn get_common_device_state_mut<D: EventDispatcher>(
    state: &mut StackState<D>,
    device: DeviceId,
) -> &mut CommonDeviceState {
    match device.protocol {
        DeviceProtocol::Ethernet => state
            .device
            .ethernet
            .get_mut(device.id)
            .unwrap_or_else(|| panic!("no such Ethernet device: {}", device.id))
            .common_mut(),
    }
}

/// Is IP packet routing enabled on `device`?
///
/// Note, `true` does not necessarily mean that `device` is currently routing IP packets. It
/// only means that `device` is allowed to route packets. To route packets, this netstack must
/// be configured to allow IP packets to be routed if it was not destined for this node.
pub(crate) fn is_routing_enabled<D: EventDispatcher, I: Ip>(
    ctx: &Context<D>,
    device: DeviceId,
) -> bool {
    match device.protocol {
        DeviceProtocol::Ethernet => self::ethernet::is_routing_enabled::<_, I>(ctx, device.id),
    }
}

/// Enables or disables IP packet routing on `device`.
///
/// `set_routing_enabled` does nothing if the new routing status, `enabled`, is the same as
/// the current routing status.
///
/// Note, enabling routing does not mean that `device` will immediately start routing IP
/// packets. It only means that `device` is allowed to route packets. To route packets, this
/// netstack must be configured to allow IP packets to be routed if it was not destined for this
/// node.
#[specialize_ip]
pub(crate) fn set_routing_enabled<D: EventDispatcher, I: Ip>(
    ctx: &mut Context<D>,
    device: DeviceId,
    enabled: bool,
) {
    // TODO(ghanan): We cannot directly do `I::VERSION` in the `trace!` calls because of a bug in
    //               specialize_ip_macro where it does not properly replace `I` with `Self`. Once
    //               this is fixed, change this.
    let version = I::VERSION;

    if crate::device::is_routing_enabled::<_, I>(ctx, device) == enabled {
        trace!(
            "set_routing_enabled: {:?} routing status unchanged for device {:?}",
            version,
            device
        );
        return;
    }

    #[ipv4]
    set_ipv4_routing_enabled(ctx, device, enabled);

    #[ipv6]
    set_ipv6_routing_enabled(ctx, device, enabled);
}

/// Sets IPv4 routing on `device`.
fn set_ipv4_routing_enabled<D: EventDispatcher>(
    ctx: &mut Context<D>,
    device: DeviceId,
    enabled: bool,
) {
    if enabled {
        trace!("set_ipv4_routing_enabled: enabling IPv4 routing for device {:?}", device);
    } else {
        trace!("set_ipv4_routing_enabled: disabling IPv4 routing for device {:?}", device);
    }

    set_routing_enabled_inner::<_, Ipv4>(ctx, device, enabled);
}

/// Sets IPv6 routing on `device`.
///
/// If the `device` transitions from a router -> host or host -> router, periodic router
/// advertisements will be stopped or started, and router solicitations will be started or stopped,
/// depending on `device`'s current and new router state.
fn set_ipv6_routing_enabled<D: EventDispatcher>(
    ctx: &mut Context<D>,
    device: DeviceId,
    enabled: bool,
) {
    let ip_routing = crate::ip::is_routing_enabled::<_, Ipv6>(ctx);

    if enabled {
        trace!("set_ipv6_routing_enabled: enabling IPv6 routing for device {:?}", device);

        // Make sure that the netstack is configured to route packets before considering this
        // device a router and stopping router solicitations. If the netstack was not configured
        // to route packets before, then we would still be considered a host, so we shouldn't
        // stop soliciting routers.
        if ip_routing {
            // TODO(ghanan): Handle transition from disabled to enabled:
            //               - start periodic router advertisements (if configured to do so)

            match device.protocol {
                DeviceProtocol::Ethernet => {
                    ndp::stop_soliciting_routers::<_, ethernet::EthernetNdpDevice>(ctx, device.id)
                }
            }
        }

        // Actually update the routing flag.
        set_routing_enabled_inner::<_, Ipv6>(ctx, device, true);

        // Make sure that the netstack is configured to route packets before considering this
        // device a router and starting periodic router advertisements.
        if ip_routing {
            // Now that `device` is a router, join the all-routers multicast group.
            join_ip_multicast(
                ctx,
                device,
                MulticastAddr::new(Ipv6::ALL_ROUTERS_LINK_LOCAL_ADDRESS).unwrap(),
            );

            if get_ndp_configurations(ctx, device)
                .get_router_configurations()
                .get_should_send_advertisements()
            {
                match device.protocol {
                    DeviceProtocol::Ethernet => ndp::start_advertising_interface::<
                        _,
                        ethernet::EthernetNdpDevice,
                    >(ctx, device.id),
                }
            }
        }
    } else {
        trace!("set_ipv6_routing_enabled: disabling IPv6 routing for device {:?}", device);

        // Make sure that the netstack is configured to route packets before considering this
        // device a router and stopping periodic router advertisements. If the netstack was not
        // configured to route packets before, then we would still be considered a host, so we
        // wouldn't have any periodic router advertisements to stop.
        if ip_routing {
            // Make sure that the device was configured to send advertisements before stopping it.
            // If it was never configured to stop advertisements, there should be nothing to stop.
            if get_ndp_configurations(ctx, device)
                .get_router_configurations()
                .get_should_send_advertisements()
            {
                match device.protocol {
                    DeviceProtocol::Ethernet => ndp::stop_advertising_interface::<
                        _,
                        ethernet::EthernetNdpDevice,
                    >(ctx, device.id),
                }
            }

            // Now that `device` is a host, leave the all-routers multicast group.
            leave_ip_multicast(
                ctx,
                device,
                MulticastAddr::new(Ipv6::ALL_ROUTERS_LINK_LOCAL_ADDRESS).unwrap(),
            );
        }

        // Actually update the routing flag.
        set_routing_enabled_inner::<_, Ipv6>(ctx, device, false);

        // We only need to start soliciting routers if we were not soliciting them before. We
        // would only reach this point if there was a change in routing status for `device`.
        // However, if the nestatck does not currently have routing enabled, the device would
        // not have been considered a router before this routing change on the device, so it
        // would have already solicited routers.
        if ip_routing {
            // On transition from router -> host, start soliciting router information.
            match device.protocol {
                DeviceProtocol::Ethernet => {
                    ndp::start_soliciting_routers::<_, ethernet::EthernetNdpDevice>(ctx, device.id)
                }
            }
        }
    }
}

/// Sets the IP packet routing flag on `device`.
fn set_routing_enabled_inner<D: EventDispatcher, I: Ip>(
    ctx: &mut Context<D>,
    device: DeviceId,
    enabled: bool,
) {
    match device.protocol {
        DeviceProtocol::Ethernet => {
            self::ethernet::set_routing_enabled_inner::<_, I>(ctx, device.id, enabled)
        }
    }
}

/// Is `device` currently operating as a router?
///
/// Returns `true` if both the `device` has routing enabled AND the netstack is configured to
/// route packets not destined for it; returns `false` otherwise.
pub(crate) fn is_router_device<D: EventDispatcher, I: Ip>(
    ctx: &Context<D>,
    device: DeviceId,
) -> bool {
    (crate::ip::is_routing_enabled::<_, I>(ctx)
        && crate::device::is_routing_enabled::<_, I>(ctx, device))
}

/// Updates the NDP Configurations for a `device`.
///
/// Note, some values may not take effect immediately, and may only take effect the next time they
/// are used. These scenarios documented below:
///
///  - Updates to [`NdpConfiguration::dup_addr_detect_transmits`] will only take effect the next
///    time Duplicate Address Detection (DAD) is done. Any DAD processes that have already started
///    will continue using the old value.
///
///  - Updates to [`NdpConfiguration::max_router_solicitations`] will only take effect the next
///    time routers are explicitly solicited. Current router solicitation will continue using the
///    old value.
pub fn set_ndp_configurations<D: EventDispatcher>(
    ctx: &mut Context<D>,
    device: DeviceId,
    configs: ndp::NdpConfigurations,
) {
    match device.protocol {
        DeviceProtocol::Ethernet => {
            ndp::set_ndp_configurations::<_, ethernet::EthernetNdpDevice>(ctx, device.id, configs)
        }
    }
}

/// Gets the NDP Configurations for a `device`.
pub fn get_ndp_configurations<D: EventDispatcher>(
    ctx: &Context<D>,
    device: DeviceId,
) -> &ndp::NdpConfigurations {
    match device.protocol {
        DeviceProtocol::Ethernet => {
            ndp::get_ndp_configurations::<_, ethernet::EthernetNdpDevice>(ctx, device.id)
        }
    }
}

/// An address that may be "tentative" in that it has not yet passed
/// duplicate address detection (DAD).
///
/// A tentative address is one for which DAD is currently being performed.
/// An address is only considered assigned to an interface once DAD has
/// completed without detecting any duplicates. See [RFC 4862] for more details.
///
/// [RFC 4862]: https://tools.ietf.org/html/rfc4862
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
pub struct Tentative<T>(T, bool);

impl<T> Tentative<T> {
    /// Create a new address that is marked as tentative.
    pub(crate) fn new_tentative(t: T) -> Self {
        Self(t, true)
    }

    /// Create a new address that is marked as permanent/assigned.
    pub(crate) fn new_permanent(t: T) -> Self {
        Self(t, false)
    }

    /// Returns whether the value is tentative.
    pub(crate) fn is_tentative(&self) -> bool {
        self.1
    }

    /// Gets the value that is stored inside.
    pub(crate) fn into_inner(self) -> T {
        self.0
    }

    /// Converts a `Tentative<T>` into a `Option<T>` in the way that
    /// a tentative value corresponds to a `None`.
    pub(crate) fn try_into_permanent(self) -> Option<T> {
        if self.is_tentative() {
            None
        } else {
            Some(self.into_inner())
        }
    }

    /// Borrow the content which is stored inside.
    pub(crate) fn inner(&self) -> &T {
        &self.0
    }

    /// Similar to `Option::map`.
    pub(crate) fn map<U, F>(self, f: F) -> Tentative<U>
    where
        F: FnOnce(T) -> U,
    {
        Tentative(f(self.0), self.1)
    }

    /// Make the tentative value to be permanent.
    pub(crate) fn mark_permanent(&mut self) {
        self.1 = false
    }
}
