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

#![cfg(test)]

use std::mem::size_of;

use fidl_fuchsia_net as net;
use fidl_fuchsia_netstack as netstack;
use fidl_fuchsia_netstack_ext::RouteTable;
use fidl_fuchsia_sys as sys;
use fuchsia_async::{self as fasync, DurationExt as _, TimeoutExt as _};
use fuchsia_component::client::AppBuilder;
use fuchsia_zircon as zx;

use anyhow::{self, Context};
use futures::{
    future, Future, FutureExt as _, StreamExt as _, TryFutureExt as _, TryStreamExt as _,
};
use net_types::ethernet::Mac;
use net_types::ip::{self as net_types_ip, Ip};
use net_types::{
    LinkLocalAddress as _, MulticastAddress as _, SpecifiedAddress as _, Witness as _,
};
use netstack_testing_common::constants::{eth as eth_consts, ipv6 as ipv6_consts};
use netstack_testing_common::environments::{KnownServices, Netstack, Netstack2};
use netstack_testing_common::{
    send_ra_with_router_lifetime, setup_network, setup_network_with, sleep, write_ndp_message,
    EthertapName, Result, ASYNC_EVENT_CHECK_INTERVAL, ASYNC_EVENT_NEGATIVE_CHECK_TIMEOUT,
    ASYNC_EVENT_POSITIVE_CHECK_TIMEOUT, NDP_MESSAGE_TTL,
};
use netstack_testing_macros::variants_test;
use packet::ParsablePacket as _;
use packet_formats::ethernet::{EtherType, EthernetFrame, EthernetFrameLengthCheck};
use packet_formats::icmp::mld::MldPacket;
use packet_formats::icmp::ndp::{
    options::{NdpOption, PrefixInformation},
    NeighborAdvertisement, NeighborSolicitation, RouterAdvertisement, RouterSolicitation,
};
use packet_formats::icmp::{IcmpParseArgs, Icmpv6Packet};
use packet_formats::ip::IpProto;
use packet_formats::testutil::{parse_icmp_packet_in_ip_packet_in_ethernet_frame, parse_ip_packet};

/// The expected number of Router Solicitations sent by the netstack when an
/// interface is brought up as a host.
const EXPECTED_ROUTER_SOLICIATIONS: u8 = 3;

/// The expected interval between sending Router Solicitation messages when
/// soliciting IPv6 routers.
const EXPECTED_ROUTER_SOLICITATION_INTERVAL: zx::Duration = zx::Duration::from_seconds(4);

/// The expected number of Neighbor Solicitations sent by the netstack when
/// performing Duplicate Address Detection.
const EXPECTED_DUP_ADDR_DETECT_TRANSMITS: u8 = 1;

/// The expected interval between sending Neighbor Solicitation messages when
/// performing Duplicate Address Detection.
const EXPECTED_DAD_RETRANSMIT_TIMER: zx::Duration = zx::Duration::from_seconds(1);

/// As per [RFC 7217 section 6] Hosts SHOULD introduce a random delay between 0 and
/// `IDGEN_DELAY` before trying a new tentative address.
///
/// [RFC 7217]: https://tools.ietf.org/html/rfc7217#section-6
const DAD_IDGEN_DELAY: zx::Duration = zx::Duration::from_seconds(1);

/// Launches a new netstack with the endpoint and returns the IPv6 addresses
/// initially assigned to it.
///
/// If `run_netstack_and_get_ipv6_addrs_for_endpoint` returns successfully, it
/// is guaranteed that the launched netstack has been terminated. Note, if
/// `run_netstack_and_get_ipv6_addrs_for_endpoint` does not return successfully,
/// the launched netstack will still be terminated, but no guarantees are made
/// about when that will happen.
async fn run_netstack_and_get_ipv6_addrs_for_endpoint<N: Netstack>(
    endpoint: &netemul::TestEndpoint<'_>,
    launcher: &sys::LauncherProxy,
    name: String,
) -> Result<Vec<net::Subnet>> {
    // Launch the netstack service.

    let mut app = AppBuilder::new(N::VERSION.get_url())
        .spawn(launcher)
        .context("failed to spawn netstack")?;
    let netstack = app
        .connect_to_service::<netstack::NetstackMarker>()
        .context("failed to connect to netstack service")?;

    // Add the device and get its interface state from netstack.
    // TODO(fxbug.dev/48907) Support Network Device. This helper fn should use stack.fidl
    // and be agnostic over interface type.
    let id = netstack
        .add_ethernet_device(
            &name,
            &mut netstack::InterfaceConfig {
                name: name[..fidl_fuchsia_posix_socket::INTERFACE_NAME_LENGTH.into()].to_string(),
                filepath: "/fake/filepath/for_test".to_string(),
                metric: 0,
            },
            endpoint
                .get_ethernet()
                .await
                .context("add_ethernet_device requires an Ethernet endpoint")?,
        )
        .await
        .context("add_ethernet_device FIDL error")?
        .map_err(fuchsia_zircon::Status::from_raw)
        .context("add_ethernet_device error")?;
    let interface = netstack
        .get_interfaces2()
        .await
        .context("failed to get interfaces")?
        .into_iter()
        .find(|interface| interface.id == id)
        .ok_or(anyhow::anyhow!("failed to find added ethernet device"))?;

    // Kill the netstack.
    //
    // Note, simply dropping `component_controller` would also kill the netstack
    // but we explicitly kill it and wait for the terminated event before
    // proceeding.
    let () = app.kill().context("failed to kill app")?;
    let _exit_status = app.wait().await.context("failed to observe netstack termination")?;

    Ok(interface.ipv6addrs)
}

/// Test that across netstack runs, a device will initially be assigned the same
/// IPv6 addresses.
#[variants_test]
async fn consistent_initial_ipv6_addrs<E: netemul::Endpoint>(name: &str) -> Result {
    let sandbox = netemul::TestSandbox::new().context("failed to create sandbox")?;
    let env = sandbox
        .create_environment(name, &[KnownServices::SecureStash])
        .context("failed to create environment")?;
    let launcher = env.get_launcher().context("failed to get launcher")?;
    let endpoint = sandbox
        .create_endpoint::<netemul::Ethernet, _>(name.ethertap_compatible_name())
        .await
        .context("failed to create endpoint")?;

    // Make sure netstack uses the same addresses across runs for a device.
    let first_run_addrs = run_netstack_and_get_ipv6_addrs_for_endpoint::<Netstack2>(
        &endpoint,
        &launcher,
        name.to_string(),
    )
    .await?;
    let second_run_addrs = run_netstack_and_get_ipv6_addrs_for_endpoint::<Netstack2>(
        &endpoint,
        &launcher,
        name.to_string(),
    )
    .await?;
    assert_eq!(first_run_addrs, second_run_addrs);

    Ok(())
}

/// Tests that `EXPECTED_ROUTER_SOLICIATIONS` Router Solicitation messages are transmitted
/// when the interface is brought up.
#[variants_test]
async fn sends_router_solicitations<E: netemul::Endpoint>(name: &str) -> Result {
    let sandbox = netemul::TestSandbox::new().context("failed to create sandbox")?;
    let (_network, _environment, _netstack, _iface, fake_ep) =
        setup_network::<E, _>(&sandbox, name).await?;

    // Make sure exactly `EXPECTED_ROUTER_SOLICIATIONS` RS messages are transmited
    // by the netstack.
    let mut observed_rs = 0;
    loop {
        // When we have already observed the expected number of RS messages, do a
        // negative check to make sure that we don't send anymore.
        let extra_timeout = if observed_rs == EXPECTED_ROUTER_SOLICIATIONS {
            ASYNC_EVENT_NEGATIVE_CHECK_TIMEOUT
        } else {
            ASYNC_EVENT_POSITIVE_CHECK_TIMEOUT
        };

        let ret = fake_ep
            .frame_stream()
            .try_filter_map(|(data, dropped)| {
                assert_eq!(dropped, 0);
                let mut observed_slls = Vec::new();
                future::ok(
                    parse_icmp_packet_in_ip_packet_in_ethernet_frame::<
                        net_types_ip::Ipv6,
                        _,
                        RouterSolicitation,
                        _,
                    >(&data, |p| {
                        for option in p.body().iter() {
                            if let NdpOption::SourceLinkLayerAddress(a) = option {
                                let mut mac_bytes = [0; 6];
                                mac_bytes.copy_from_slice(&a[..size_of::<Mac>()]);
                                observed_slls.push(Mac::new(mac_bytes));
                            } else {
                                // We should only ever have an NDP Source Link-Layer Address
                                // option in a RS.
                                panic!("unexpected option in RS = {:?}", option);
                            }
                        }
                    })
                    .map_or(
                        None,
                        |(_src_mac, dst_mac, src_ip, dst_ip, ttl, _message, _code)| {
                            Some((dst_mac, src_ip, dst_ip, ttl, observed_slls))
                        },
                    ),
                )
            })
            .try_next()
            .map(|r| r.context("error getting OnData event"))
            .on_timeout((EXPECTED_ROUTER_SOLICITATION_INTERVAL + extra_timeout).after_now(), || {
                // If we already observed `EXPECTED_ROUTER_SOLICIATIONS` RS, then we shouldn't
                // have gotten any more; the timeout is expected.
                if observed_rs == EXPECTED_ROUTER_SOLICIATIONS {
                    return Ok(None);
                }

                return Err(anyhow::anyhow!("timed out waiting for the {}-th RS", observed_rs));
            })
            .await?;

        let (dst_mac, src_ip, dst_ip, ttl, observed_slls) = match ret {
            Some((dst_mac, src_ip, dst_ip, ttl, observed_slls)) => {
                (dst_mac, src_ip, dst_ip, ttl, observed_slls)
            }
            None => break,
        };

        assert_eq!(
            dst_mac,
            Mac::from(&net_types_ip::Ipv6::ALL_ROUTERS_LINK_LOCAL_MULTICAST_ADDRESS)
        );

        // DAD should have resolved for the link local IPv6 address that is assigned to
        // the interface when it is first brought up. When a link local address is
        // assigned to the interface, it should be used for transmitted RS messages.
        if observed_rs > 0 {
            assert!(src_ip.is_specified())
        }

        assert_eq!(dst_ip, net_types_ip::Ipv6::ALL_ROUTERS_LINK_LOCAL_MULTICAST_ADDRESS.get());

        assert_eq!(ttl, NDP_MESSAGE_TTL);

        // The Router Solicitation should only ever have at max 1 source
        // link-layer option.
        assert!(observed_slls.len() <= 1);
        let observed_sll = observed_slls.into_iter().nth(0);
        if src_ip.is_specified() {
            if observed_sll.is_none() {
                panic!("expected source-link-layer address option if RS has a specified source IP address");
            }
        } else if observed_sll.is_some() {
            panic!("unexpected source-link-layer address option for RS with unspecified source IP address");
        }

        observed_rs += 1;
    }

    assert_eq!(observed_rs, EXPECTED_ROUTER_SOLICIATIONS);

    Ok(())
}

/// Tests that both stable and temporary SLAAC addresses are generated for a SLAAC prefix.
#[variants_test]
async fn slaac_with_privacy_extensions<E: netemul::Endpoint>(name: &str) -> Result {
    let sandbox = netemul::TestSandbox::new().context("failed to create sandbox")?;
    let (_network, environment, _netstack, iface, fake_ep) =
        setup_network::<E, _>(&sandbox, name).await?;

    // Wait for a Router Solicitation.
    //
    // The first RS should be sent immediately.
    let () = fake_ep
        .frame_stream()
        .try_filter_map(|(data, dropped)| {
            assert_eq!(dropped, 0);
            future::ok(
                parse_icmp_packet_in_ip_packet_in_ethernet_frame::<
                    net_types_ip::Ipv6,
                    _,
                    RouterSolicitation,
                    _,
                >(&data, |_| {})
                .map_or(None, |_| Some(())),
            )
        })
        .try_next()
        .map(|r| r.context("error getting OnData event"))
        .on_timeout(ASYNC_EVENT_POSITIVE_CHECK_TIMEOUT.after_now(), || {
            Err(anyhow::anyhow!("timed out waiting for RS packet"))
        })
        .await?
        .ok_or(anyhow::anyhow!("failed to get next OnData event"))?;

    // Send a Router Advertisement with information for a SLAAC prefix.
    let ra = RouterAdvertisement::new(
        0,     /* current_hop_limit */
        false, /* managed_flag */
        false, /* other_config_flag */
        0,     /* router_lifetime */
        0,     /* reachable_time */
        0,     /* retransmit_timer */
    );
    let pi = PrefixInformation::new(
        ipv6_consts::PREFIX.prefix(),  /* prefix_length */
        false,                         /* on_link_flag */
        true,                          /* autonomous_address_configuration_flag */
        99999,                         /* valid_lifetime */
        99999,                         /* preferred_lifetime */
        ipv6_consts::PREFIX.network(), /* prefix */
    );
    let options = [NdpOption::PrefixInformation(&pi)];
    let () = write_ndp_message::<&[u8], _>(
        eth_consts::MAC_ADDR,
        Mac::from(&net_types_ip::Ipv6::ALL_NODES_LINK_LOCAL_MULTICAST_ADDRESS),
        ipv6_consts::LINK_LOCAL_ADDR,
        net_types_ip::Ipv6::ALL_NODES_LINK_LOCAL_MULTICAST_ADDRESS.get(),
        ra,
        &options,
        &fake_ep,
    )
    .await
    .context("failed to write NDP message")?;

    // Wait for the SLAAC addresses to be generated.
    //
    // We expect two addresses for the SLAAC prefixes to be assigned to the NIC as the
    // netstack should generate both a stable and temporary SLAAC address.
    let interface_state = environment
        .connect_to_service::<fidl_fuchsia_net_interfaces::StateMarker>()
        .context("failed to connect to fuchsia.net.interfaces/State")?;
    let expected_addrs = 2;
    fidl_fuchsia_net_interfaces_ext::wait_interface_with_id(
        fidl_fuchsia_net_interfaces_ext::event_stream_from_state(&interface_state)?,
        &mut fidl_fuchsia_net_interfaces_ext::InterfaceState::Unknown(iface.id()),
        |fidl_fuchsia_net_interfaces_ext::Properties { addresses, .. }| {
            if addresses
                .iter()
                .filter_map(
                    |&fidl_fuchsia_net_interfaces_ext::Address {
                         addr: fidl_fuchsia_net::Subnet { addr, prefix_len: _ },
                     }| {
                        match addr {
                            net::IpAddress::Ipv4(net::Ipv4Address { addr: _ }) => None,
                            net::IpAddress::Ipv6(net::Ipv6Address { addr }) => {
                                // TODO(https://github.com/rust-lang/rust/issues/80967): use bool::then_some.
                                ipv6_consts::PREFIX
                                    .contains(&net_types_ip::Ipv6Addr::new(addr))
                                    .then(|| ())
                            }
                        }
                    },
                )
                .count()
                == expected_addrs as usize
            {
                Some(())
            } else {
                None
            }
        },
    )
    .map_err(anyhow::Error::from)
    .on_timeout(
        (EXPECTED_DAD_RETRANSMIT_TIMER * EXPECTED_DUP_ADDR_DETECT_TRANSMITS * expected_addrs
            + ASYNC_EVENT_POSITIVE_CHECK_TIMEOUT)
            .after_now(),
        || Err(anyhow::anyhow!("timed out")),
    )
    .await
    .context("failed to wait for SLAAC addresses to be generated")
}

/// Adds `ipv6_consts::LINK_LOCAL_ADDR` to the interface and makes sure a Neighbor Solicitation
/// message is transmitted by the netstack for DAD.
///
/// Calls `fail_dad_fn` after the DAD message is observed so callers can simulate a remote
/// node that has some interest in the same address.
async fn add_address_for_dad<
    'a,
    'b: 'a,
    R: 'b + Future<Output = Result>,
    FN: FnOnce(&'b netemul::TestInterface<'a>, &'b netemul::TestFakeEndpoint<'a>) -> R,
>(
    iface: &'b netemul::TestInterface<'a>,
    fake_ep: &'b netemul::TestFakeEndpoint<'a>,
    fail_dad_fn: FN,
) -> Result {
    let () = iface
        .add_ip_addr(net::Subnet {
            addr: net::IpAddress::Ipv6(net::Ipv6Address {
                addr: ipv6_consts::LINK_LOCAL_ADDR.ipv6_bytes(),
            }),
            prefix_len: 64,
        })
        .await?;

    // The first DAD message should be sent immediately.
    let ret = fake_ep
        .frame_stream()
        .try_filter_map(|(data, dropped)| {
            assert_eq!(dropped, 0);
            future::ok(
                parse_icmp_packet_in_ip_packet_in_ethernet_frame::<
                    net_types_ip::Ipv6,
                    _,
                    NeighborSolicitation,
                    _,
                >(&data, |p| assert_eq!(p.body().iter().count(), 0))
                .map_or(None, |(_src_mac, dst_mac, src_ip, dst_ip, ttl, message, _code)| {
                    // If the NS is not for the address we just added, this is for some
                    // other address. We ignore it as it is not relevant to our test.
                    if message.target_address() != &ipv6_consts::LINK_LOCAL_ADDR {
                        return None;
                    }

                    Some((dst_mac, src_ip, dst_ip, ttl))
                }),
            )
        })
        .try_next()
        .map(|r| r.context("error getting OnData event"))
        .on_timeout(ASYNC_EVENT_POSITIVE_CHECK_TIMEOUT.after_now(), || {
            Err(anyhow::anyhow!(
                "timed out waiting for a neighbor solicitation targetting {}",
                ipv6_consts::LINK_LOCAL_ADDR
            ))
        })
        .await?
        .ok_or(anyhow::anyhow!("failed to get next OnData event"))?;

    let (dst_mac, src_ip, dst_ip, ttl) = ret;
    let expected_dst = ipv6_consts::LINK_LOCAL_ADDR.to_solicited_node_address();
    assert_eq!(src_ip, net_types_ip::Ipv6::UNSPECIFIED_ADDRESS);
    assert_eq!(dst_ip, expected_dst.get());
    assert_eq!(dst_mac, Mac::from(&expected_dst));
    assert_eq!(ttl, NDP_MESSAGE_TTL);

    let () = fail_dad_fn(iface, fake_ep).await?;

    Ok(())
}

/// Tests that if the netstack attempts to assign an address to an interface, and a remote node
/// is already assigned the address or attempts to assign the address at the same time, DAD
/// fails on the local interface.
///
/// If no remote node has any interest in an address the netstack is attempting to assign to
/// an interface, DAD should succeed.
#[variants_test]
async fn duplicate_address_detection<E: netemul::Endpoint>(name: &str) -> Result {
    /// Makes sure that `ipv6_consts::LINK_LOCAL_ADDR` is not assigned to the interface after the
    /// DAD resolution time.
    async fn check_address_failed_dad(iface: &netemul::TestInterface<'_>) -> Result {
        // Clocks sometimes jump in infrastructure, which can cause a timer to expire prematurely.
        // Fortunately such jumps are rarely seen in quick succession - if we repeatedly wait for
        // shorter durations we can be reasonably sure that the intended amount of time truly did
        // elapse. It is expected that at most one timer worth of time may be lost.
        const STEP: zx::Duration = zx::Duration::from_millis(10);
        let duration = EXPECTED_DAD_RETRANSMIT_TIMER * EXPECTED_DUP_ADDR_DETECT_TRANSMITS
            + ASYNC_EVENT_NEGATIVE_CHECK_TIMEOUT;
        let iterations =
            (duration + STEP - zx::Duration::from_nanos(1)).into_micros() / STEP.into_micros();
        for _ in 0..iterations {
            let () = fasync::Timer::new(fasync::Time::after(STEP)).await;
        }

        let addr = net::Subnet {
            addr: net::IpAddress::Ipv6(net::Ipv6Address {
                addr: ipv6_consts::LINK_LOCAL_ADDR.ipv6_bytes(),
            }),
            prefix_len: 64,
        };
        assert!(!iface.get_addrs().await?.iter().any(|a| a == &addr));

        Ok(())
    }

    /// Transmits a Neighbor Solicitation message and expects `ipv6_consts::LINK_LOCAL_ADDR`
    /// to not be assigned to the interface after the normal resolution time for DAD.
    async fn fail_dad_with_ns(
        iface: &netemul::TestInterface<'_>,
        fake_ep: &netemul::TestFakeEndpoint<'_>,
    ) -> Result {
        let snmc = ipv6_consts::LINK_LOCAL_ADDR.to_solicited_node_address();
        let () = write_ndp_message::<&[u8], _>(
            eth_consts::MAC_ADDR,
            Mac::from(&snmc),
            net_types_ip::Ipv6::UNSPECIFIED_ADDRESS,
            snmc.get(),
            NeighborSolicitation::new(ipv6_consts::LINK_LOCAL_ADDR),
            &[],
            fake_ep,
        )
        .await
        .context("failed to write NDP message")?;

        check_address_failed_dad(iface).await
    }

    /// Transmits a Neighbor Advertisement message and expects `ipv6_consts::LINK_LOCAL_ADDR`
    /// to not be assigned to the interface after the normal resolution time for DAD.
    async fn fail_dad_with_na(
        iface: &netemul::TestInterface<'_>,
        fake_ep: &netemul::TestFakeEndpoint<'_>,
    ) -> Result {
        let () = write_ndp_message::<&[u8], _>(
            eth_consts::MAC_ADDR,
            Mac::from(&net_types_ip::Ipv6::ALL_NODES_LINK_LOCAL_MULTICAST_ADDRESS),
            ipv6_consts::LINK_LOCAL_ADDR,
            net_types_ip::Ipv6::ALL_NODES_LINK_LOCAL_MULTICAST_ADDRESS.get(),
            NeighborAdvertisement::new(
                false, /* router_flag */
                false, /* solicited_flag */
                false, /* override_flag */
                ipv6_consts::LINK_LOCAL_ADDR,
            ),
            &[NdpOption::TargetLinkLayerAddress(&eth_consts::MAC_ADDR.bytes())],
            fake_ep,
        )
        .await
        .context("failed to write NDP message")?;

        check_address_failed_dad(iface).await
    }

    let sandbox = netemul::TestSandbox::new().context("failed to create sandbox")?;
    let (_network, environment, _netstack, iface, fake_ep) =
        setup_network::<E, _>(&sandbox, name).await?;

    // Add an address and expect it to fail DAD because we simulate another node
    // performing DAD at the same time.
    let () = add_address_for_dad(&iface, &fake_ep, fail_dad_with_ns).await?;

    // Add an address and expect it to fail DAD because we simulate another node
    // already owning the address.
    let () = add_address_for_dad(&iface, &fake_ep, fail_dad_with_na).await?;

    // Add the address, and make sure it gets assigned.
    let () = add_address_for_dad(&iface, &fake_ep, |_, _| async { Ok(()) }).await?;

    let interface_state = environment
        .connect_to_service::<fidl_fuchsia_net_interfaces::StateMarker>()
        .context("failed to connect to fuchsia.net.interfaces/State")?;
    fidl_fuchsia_net_interfaces_ext::wait_interface_with_id(
        fidl_fuchsia_net_interfaces_ext::event_stream_from_state(&interface_state)?,
        &mut fidl_fuchsia_net_interfaces_ext::InterfaceState::Unknown(iface.id()),
        |fidl_fuchsia_net_interfaces_ext::Properties { addresses, .. }| {
            addresses.iter().find_map(
                |&fidl_fuchsia_net_interfaces_ext::Address {
                     addr: fidl_fuchsia_net::Subnet { addr, prefix_len: _ },
                 }| {
                    match addr {
                        net::IpAddress::Ipv6(net::Ipv6Address { addr }) => {
                            if ipv6_consts::LINK_LOCAL_ADDR == net_types_ip::Ipv6Addr::new(addr) {
                                Some(())
                            } else {
                                None
                            }
                        }
                        net::IpAddress::Ipv4(_) => None,
                    }
                },
            )
        },
    )
    .map_err(anyhow::Error::from)
    .on_timeout(
        (EXPECTED_DAD_RETRANSMIT_TIMER * EXPECTED_DUP_ADDR_DETECT_TRANSMITS
            + ASYNC_EVENT_POSITIVE_CHECK_TIMEOUT)
            .after_now(),
        || Err(anyhow::anyhow!("timed out")),
    )
    .await
    .with_context(|| {
        format!("failed to wait for address {} to be assigned", ipv6_consts::LINK_LOCAL_ADDR)
    })
}

#[variants_test]
async fn router_and_prefix_discovery<E: netemul::Endpoint>(name: &str) -> Result {
    async fn check_route_table<P>(netstack: &netstack::NetstackProxy, pred: P) -> Result<()>
    where
        P: Fn(&Vec<netstack::RouteTableEntry>) -> bool,
    {
        let check_attempts = ASYNC_EVENT_POSITIVE_CHECK_TIMEOUT.into_seconds()
            / ASYNC_EVENT_CHECK_INTERVAL.into_seconds();
        for attempt in 0..check_attempts {
            let () = sleep(ASYNC_EVENT_CHECK_INTERVAL.into_seconds()).await;
            let route_table =
                netstack.get_route_table().await.context("failed to get route table")?;
            if pred(&route_table) {
                return Ok(());
            } else {
                let route_table = RouteTable::new(route_table)
                    .display()
                    .context("failed to format route table")?;
                println!("route table at attempt={}:\n{}", attempt, route_table);
            }
        }
        Err(anyhow::anyhow!(
            "timed out on waiting for a route table entry after {} seconds",
            ASYNC_EVENT_POSITIVE_CHECK_TIMEOUT.into_seconds(),
        ))
    }

    let sandbox = netemul::TestSandbox::new().context("failed to create sandbox")?;
    let (_network, _environment, netstack, iface, fake_ep) =
        setup_network::<E, _>(&sandbox, name).await.context("failed to setup network")?;

    let pi = PrefixInformation::new(
        ipv6_consts::PREFIX.prefix(),  /* prefix_length */
        true,                          /* on_link_flag */
        false,                         /* autonomous_address_configuration_flag */
        1000,                          /* valid_lifetime */
        0,                             /* preferred_lifetime */
        ipv6_consts::PREFIX.network(), /* prefix */
    );
    let options = [NdpOption::PrefixInformation(&pi)];
    let () = send_ra_with_router_lifetime(&fake_ep, 1000, &options)
        .await
        .context("failed to send router advertisement")?;

    // Test that the default router should be discovered after it is advertised.
    let () = check_route_table(&netstack, |route_table| {
        route_table.iter().any(|netstack::RouteTableEntry { destination, gateway, .. }| {
            if let net::IpAddress::Ipv6(gateway) = gateway {
                if let net::IpAddress::Ipv6(destination) = destination {
                    let gateway = net_types_ip::Ipv6Addr::new(gateway.addr);
                    let destination = net_types_ip::Ipv6Addr::new(destination.addr);
                    if destination == net_types_ip::Ipv6::UNSPECIFIED_ADDRESS
                        && gateway == ipv6_consts::LINK_LOCAL_ADDR
                    {
                        return true;
                    }
                }
            }
            false
        })
    })
    .await
    .context("failed when checking route table for default route")?;

    // Test that the prefix should be discovered after it is advertised.
    let () = check_route_table(&netstack, |route_table| {
        route_table.iter().any(|netstack::RouteTableEntry { destination, nicid, .. }| {
            if let net::IpAddress::Ipv6(dest) = destination {
                let destination = net_types_ip::Ipv6Addr::new(dest.addr);
                if destination == ipv6_consts::PREFIX.network() && u64::from(*nicid) == iface.id() {
                    return true;
                }
            }
            false
        })
    })
    .await
    .context("failed when checking route table for the on-link route")?;

    Ok(())
}

#[variants_test]
async fn slaac_regeneration_after_dad_failure<E: netemul::Endpoint>(name: &str) -> Result {
    // Expects an NS message for DAD within timeout and returns the target address of the message.
    async fn expect_ns_message_in(
        fake_ep: &netemul::TestFakeEndpoint<'_>,
        timeout: zx::Duration,
    ) -> Result<net_types_ip::Ipv6Addr> {
        fake_ep
            .frame_stream()
            .try_filter_map(|(data, dropped)| {
                assert_eq!(dropped, 0);
                future::ok(
                    parse_icmp_packet_in_ip_packet_in_ethernet_frame::<
                        net_types_ip::Ipv6,
                        _,
                        NeighborSolicitation,
                        _,
                    >(&data, |p| assert_eq!(p.body().iter().count(), 0))
                    .map_or(None, |(_src_mac, _dst_mac, _src_ip, _dst_ip, _ttl, message, _code)| {
                        // If the NS target_address does not have the prefix we have advertised,
                        // this is for some other address. We ignore it as it is not relevant to
                        // our test.
                        if !ipv6_consts::PREFIX.contains(message.target_address()) {
                            return None;
                        }

                        Some(*message.target_address())
                    }),
                )
            })
            .try_next()
            .map(|r| r.context("error getting OnData event"))
            .on_timeout(timeout.after_now(), || {
                Err(anyhow::anyhow!(
                    "timed out waiting for a neighbor solicitation targetting address of prefix: {}",
                    ipv6_consts::PREFIX,
                ))
            })
            .await?
            .ok_or(anyhow::anyhow!("failed to get next OnData event"))
    }

    let sandbox = netemul::TestSandbox::new().context("failed to create sandbox")?;
    let (_network, environment, _netstack, iface, fake_ep) =
        setup_network_with::<E, _, _>(&sandbox, name, &[KnownServices::SecureStash]).await?;

    // Send a Router Advertisement with information for a SLAAC prefix.
    let ra = RouterAdvertisement::new(
        0,     /* current_hop_limit */
        false, /* managed_flag */
        false, /* other_config_flag */
        0,     /* router_lifetime */
        0,     /* reachable_time */
        0,     /* retransmit_timer */
    );
    let pi = PrefixInformation::new(
        ipv6_consts::PREFIX.prefix(),  /* prefix_length */
        false,                         /* on_link_flag */
        true,                          /* autonomous_address_configuration_flag */
        99999,                         /* valid_lifetime */
        99999,                         /* preferred_lifetime */
        ipv6_consts::PREFIX.network(), /* prefix */
    );
    let options = [NdpOption::PrefixInformation(&pi)];
    let () = write_ndp_message::<&[u8], _>(
        eth_consts::MAC_ADDR,
        Mac::from(&net_types_ip::Ipv6::ALL_NODES_LINK_LOCAL_MULTICAST_ADDRESS),
        ipv6_consts::LINK_LOCAL_ADDR,
        net_types_ip::Ipv6::ALL_NODES_LINK_LOCAL_MULTICAST_ADDRESS.get(),
        ra,
        &options,
        &fake_ep,
    )
    .await
    .context("failed to write RA message")?;

    let tried_address = expect_ns_message_in(&fake_ep, ASYNC_EVENT_POSITIVE_CHECK_TIMEOUT)
        .await
        .context("failed to get a neighbour solicitation")?;

    // We pretend there is a duplicate address situation.
    let snmc = tried_address.to_solicited_node_address();
    let () = write_ndp_message::<&[u8], _>(
        eth_consts::MAC_ADDR,
        Mac::from(&snmc),
        net_types_ip::Ipv6::UNSPECIFIED_ADDRESS,
        snmc.get(),
        NeighborSolicitation::new(tried_address),
        &[],
        &fake_ep,
    )
    .await
    .context("failed to write DAD message")?;

    let target_address =
        expect_ns_message_in(&fake_ep, DAD_IDGEN_DELAY + ASYNC_EVENT_POSITIVE_CHECK_TIMEOUT)
            .await
            .context("failed to get a neighbour solicitation")?;

    // We expect two addresses for the SLAAC prefixes to be assigned to the NIC as the
    // netstack should generate both a stable and temporary SLAAC address.
    let expected_addrs = 2;
    let interface_state = environment
        .connect_to_service::<fidl_fuchsia_net_interfaces::StateMarker>()
        .context("failed to connect to fuchsia.net.interfaces/State")?;
    let () = fidl_fuchsia_net_interfaces_ext::wait_interface_with_id(
        fidl_fuchsia_net_interfaces_ext::event_stream_from_state(&interface_state)?,
        &mut fidl_fuchsia_net_interfaces_ext::InterfaceState::Unknown(iface.id()),
        |fidl_fuchsia_net_interfaces_ext::Properties { addresses, .. }| {
            // We have to make sure 2 things:
            // 1. We have `expected_addrs` addrs which have the advertised prefix for the
            // interface.
            // 2. The last tried address should be among the addresses for the interface.
            let (slaac_addrs, has_target_addr) = addresses.iter().fold(
                (0, false),
                |(mut slaac_addrs, mut has_target_addr), &fidl_fuchsia_net_interfaces_ext::Address { addr: fidl_fuchsia_net::Subnet { addr, prefix_len: _ } }| {
                    match addr {
                        net::IpAddress::Ipv6(net::Ipv6Address { addr }) => {
                            let configured_addr = net_types_ip::Ipv6Addr::new(addr);
                            assert!(configured_addr != tried_address,
                                "unexpected address ({}) assigned to the interface which previously failed DAD",
                                configured_addr
                            );
                            if ipv6_consts::PREFIX.contains(&configured_addr) {
                                slaac_addrs += 1;
                            }
                            if configured_addr == target_address {
                                has_target_addr = true;
                            }
                        }
                        net::IpAddress::Ipv4(_) => {}
                    }
                    (slaac_addrs, has_target_addr)
                },
            );

            assert!(
                slaac_addrs <= expected_addrs,
                "more addresses found than expected, found {}, expected {}",
                slaac_addrs,
                expected_addrs
            );
            if slaac_addrs == expected_addrs && has_target_addr {
                Some(())
            } else {
                None
            }
        },
    )
    .map_err(anyhow::Error::from)
    .on_timeout(
        (EXPECTED_DAD_RETRANSMIT_TIMER * EXPECTED_DUP_ADDR_DETECT_TRANSMITS * expected_addrs
            + ASYNC_EVENT_POSITIVE_CHECK_TIMEOUT)
            .after_now(),
        || Err(anyhow::anyhow!("timed out")),
    )
    .await
    .context("failed to wait for SLAAC addresses")?;
    Ok(())
}

#[variants_test]
async fn sends_mld_reports<E: netemul::Endpoint>(name: &str) -> Result {
    let sandbox = netemul::TestSandbox::new().context("error creating sandbox")?;
    let (_network, _environment, _netstack, iface, fake_ep) =
        setup_network::<E, _>(&sandbox, name).await.context("error setting up networking")?;

    // Add an address so we join the address's solicited node multicast group.
    let () = iface
        .add_ip_addr(net::Subnet {
            addr: net::IpAddress::Ipv6(net::Ipv6Address {
                addr: ipv6_consts::LINK_LOCAL_ADDR.ipv6_bytes(),
            }),
            prefix_len: 64,
        })
        .await
        .context("error adding IP address")?;
    let snmc = ipv6_consts::LINK_LOCAL_ADDR.to_solicited_node_address();

    let stream = fake_ep
        .frame_stream()
        .map(|r| r.context("error getting OnData event"))
        .try_filter_map(|(data, dropped)| {
            async move {
                assert_eq!(dropped, 0);
                let mut data = &data[..];

                let eth = EthernetFrame::parse(&mut data, EthernetFrameLengthCheck::Check)
                    .context("error parsing ethernet frame")?;

                if eth.ethertype() != Some(EtherType::Ipv6) {
                    // Ignore non-IPv6 packets.
                    return Ok(None);
                }

                let (mut payload, src_ip, dst_ip, proto, ttl) =
                    parse_ip_packet::<net_types_ip::Ipv6>(&data)
                        .context("error parsing IPv6 packet")?;

                if proto != IpProto::Icmpv6 {
                    // Ignore non-ICMPv6 packets.
                    return Ok(None);
                }

                let icmp = Icmpv6Packet::parse(&mut payload, IcmpParseArgs::new(src_ip, dst_ip))
                    .context("error parsing ICMPv6 packet")?;

                let mld = if let Icmpv6Packet::Mld(mld) = icmp {
                    mld
                } else {
                    // Ignore non-MLD packets.
                    return Ok(None);
                };

                // As per RFC 3590 section 4,
                //
                //   MLD Report and Done messages are sent with a link-local address as
                //   the IPv6 source address, if a valid address is available on the
                //   interface. If a valid link-local address is not available (e.g., one
                //   has not been configured), the message is sent with the unspecified
                //   address (::) as the IPv6 source address.
                assert!(!src_ip.is_specified() || src_ip.is_linklocal(), "MLD messages must be sent from the unspecified or link local address; src_ip = {}", src_ip);

                assert!(dst_ip.is_multicast(), "all MLD messages must be sent to a multicast address; dst_ip = {}", dst_ip);

                // As per RFC 2710 section 3,
                //
                //   All MLD messages described in this document are sent with a
                //   link-local IPv6 Source Address, an IPv6 Hop Limit of 1, ...
                assert_eq!(ttl, 1, "MLD messages must have a hop limit of 1");

                let report = if let MldPacket::MulticastListenerReport(report) = mld {
                    report
                } else {
                    // Ignore non-report messages.
                    return Ok(None);
                };

                let group_addr = report.body().group_addr;
                assert!(group_addr.is_multicast(),  "MLD reports must only be sent for multicast addresses; group_addr = {}", group_addr);

                if group_addr != *snmc {
                    // We are only interested in the report for the solicited node
                    // multicast group we joined.
                    return Ok(None);
                }

                assert_eq!(dst_ip, group_addr, "the destination of an MLD report should be the multicast group the report is for");

                Ok(Some(()))
            }
        });
    futures::pin_mut!(stream);
    let () = stream
        .try_next()
        .on_timeout(ASYNC_EVENT_POSITIVE_CHECK_TIMEOUT.after_now(), || {
            return Err(anyhow::anyhow!("timed out waiting for the MLD report"));
        })
        .await?
        .context("error getting our expected MLD report")?;

    Ok(())
}
