[net-types] Introduce `Witness` trait
- Introduce the `Witness` trait; `Witness<A>` is implemented by
any witness type (`SpecifiedAddr<A>`, `UnicastAddr<A>`, etc) which
is a witness to some property about the address `A`
- Introduce the `IpAddrWitness: Witness<IpAddr>` trait, which
provides useful associated types
- Modify `AddrSubnet` and `AddrSubnetEither` to be generic over
which witness type is used as opposed to only supporting
`SpecifiedAddr`
Test: Very little behavior change, although added one test case to
make sure that `AddrSubnet::new` properly rejects addresses
based on the witness type which is used
Change-Id: I12ea1f7b5f0892e7fa625864a454e4585b92701f
diff --git a/src/connectivity/lib/net-types/src/ethernet.rs b/src/connectivity/lib/net-types/src/ethernet.rs
index 90a6e0a..bb2920d 100644
--- a/src/connectivity/lib/net-types/src/ethernet.rs
+++ b/src/connectivity/lib/net-types/src/ethernet.rs
@@ -9,7 +9,9 @@
use zerocopy::{AsBytes, FromBytes, Unaligned};
use crate::ip::{IpAddress, Ipv6Addr};
-use crate::{BroadcastAddress, LinkLocalAddr, MulticastAddr, MulticastAddress, UnicastAddress};
+use crate::{
+ BroadcastAddress, LinkLocalAddr, MulticastAddr, MulticastAddress, UnicastAddress, Witness,
+};
/// A media access control (MAC) address.
///
diff --git a/src/connectivity/lib/net-types/src/ip.rs b/src/connectivity/lib/net-types/src/ip.rs
index 1f95fa79..d6dda51 100644
--- a/src/connectivity/lib/net-types/src/ip.rs
+++ b/src/connectivity/lib/net-types/src/ip.rs
@@ -59,7 +59,7 @@
use crate::{
sealed, LinkLocalAddr, LinkLocalAddress, MulticastAddr, MulticastAddress, SpecifiedAddr,
- SpecifiedAddress, UnicastAddress,
+ SpecifiedAddress, UnicastAddress, Witness,
};
// NOTE on passing by reference vs by value: Clippy advises us to pass IPv4
@@ -1002,70 +1002,105 @@
///
/// An `AddrSubnet` is a pair of an address and a subnet which maintains the
/// invariant that the address is guaranteed to be a unicast address in the
-/// subnet.
+/// subnet. `S` is the type of address ([`Ipv4Addr`] or [`Ipv6Addr`]), and `A`
+/// is the type of the address in the subnet, which is always a witness wrapper
+/// around `S`. By default, it is `SpecifiedAddr<S>`.
#[derive(Copy, Clone, Eq, PartialEq, Debug, Hash)]
-pub struct AddrSubnet<A: IpAddress> {
+pub struct AddrSubnet<S: IpAddress, A: Witness<S> = SpecifiedAddr<S>> {
// TODO(joshlf): Would it be more performant to store these as just an
// address and subnet mask? It would make the object smaller and so cheaper
// to pass around, but it would make certain operations more expensive.
- addr: SpecifiedAddr<A>,
- subnet: Subnet<A>,
+ addr: A,
+ subnet: Subnet<S>,
}
-impl<A: IpAddress> AddrSubnet<A> {
+impl<S: IpAddress, A: Witness<S>> AddrSubnet<S, A> {
/// Creates a new `AddrSubnet`.
///
/// `new` creates a new `AddrSubnet` with the given address and prefix
/// length. The network address of the subnet is taken to be the first
/// `prefix` bits of the address. It returns `None` if `prefix` is longer
/// than the number of bits in this type of IP address (32 for IPv4 and 128
- /// for IPv6) or if `addr` is not a unicast address in the resulting subnet
- /// (see [`IpAddress::is_unicast_in_subnet`]).
+ /// for IPv6), if `addr` is not a unicast address in the resulting subnet
+ /// (see [`IpAddress::is_unicast_in_subnet`]), or if `addr` does not satisfy
+ /// the requirements of the witness type `A`.
#[inline]
- pub fn new(addr: A, prefix: u8) -> Option<AddrSubnet<A>> {
- if prefix > A::BYTES * 8 {
+ pub fn new(addr: S, prefix: u8) -> Option<AddrSubnet<S, A>> {
+ if prefix > S::BYTES * 8 {
return None;
}
let subnet = Subnet { network: addr.mask(prefix), prefix };
if !addr.is_unicast_in_subnet(&subnet) {
return None;
}
- let addr = SpecifiedAddr::new(addr)?;
+ let addr = A::new(addr)?;
Some(AddrSubnet { addr, subnet })
}
- /// Gets the address.
- #[inline]
- pub fn addr(&self) -> SpecifiedAddr<A> {
- self.addr
- }
-
/// Gets the subnet.
#[inline]
- pub fn subnet(&self) -> Subnet<A> {
+ pub fn subnet(&self) -> Subnet<S> {
self.subnet
}
/// Consumes the `AddrSubnet` and returns the address.
#[inline]
- pub fn into_addr(self) -> SpecifiedAddr<A> {
+ pub fn into_addr(self) -> A {
self.addr
}
/// Consumes the `AddrSubnet` and returns the subnet.
#[inline]
- pub fn into_subnet(self) -> Subnet<A> {
+ pub fn into_subnet(self) -> Subnet<S> {
self.subnet
}
/// Consumes the `AddrSubnet` and returns the address and subnet
/// individually.
#[inline]
- pub fn into_addr_subnet(self) -> (SpecifiedAddr<A>, Subnet<A>) {
+ pub fn into_addr_subnet(self) -> (A, Subnet<S>) {
(self.addr, self.subnet)
}
}
+impl<S: IpAddress, A: Witness<S> + Copy> AddrSubnet<S, A> {
+ /// Gets the address.
+ #[inline]
+ pub fn addr(&self) -> A {
+ self.addr
+ }
+}
+
+/// A type which is a witness to some property about an `IpAddress`.
+///
+/// `IpAddrWitness` extends [`Witness`] by adding associated types for the IPv4-
+/// and IPv6-specific versions of the same witness type. For example, the
+/// following implementation is provided for `SpecifiedAddr<IpAddr>`:
+///
+/// ```rust,ignore
+/// impl IpAddrWitness for SpecifiedAddr<IpAddr> {
+/// type V4 = SpecifiedAddr<Ipv4Addr>;
+/// type V6 = SpecifiedAddr<Ipv6Addr>;
+/// }
+/// ```
+pub trait IpAddrWitness: Witness<IpAddr> {
+ type V4: Witness<Ipv4Addr> + Into<Self>;
+ type V6: Witness<Ipv6Addr> + Into<Self>;
+}
+
+macro_rules! impl_ip_addr_witness {
+ ($witness:ident) => {
+ impl IpAddrWitness for $witness<IpAddr> {
+ type V4 = $witness<Ipv4Addr>;
+ type V6 = $witness<Ipv6Addr>;
+ }
+ };
+}
+
+impl_ip_addr_witness!(SpecifiedAddr);
+impl_ip_addr_witness!(MulticastAddr);
+impl_ip_addr_witness!(LinkLocalAddr);
+
/// An address and that address' subnet, either IPv4 or IPv6.
///
/// `AddrSubnetEither` is an enum of [`AddrSubnet<Ipv4Addr>`] and
@@ -1074,21 +1109,19 @@
/// [`AddrSubnet<Ipv4Addr>`]: crate::ip::AddrSubnet
#[allow(missing_docs)]
#[derive(Copy, Clone, Eq, PartialEq, Debug, Hash)]
-pub enum AddrSubnetEither {
- V4(AddrSubnet<Ipv4Addr>),
- V6(AddrSubnet<Ipv6Addr>),
+pub enum AddrSubnetEither<A: IpAddrWitness = SpecifiedAddr<IpAddr>> {
+ V4(AddrSubnet<Ipv4Addr, A::V4>),
+ V6(AddrSubnet<Ipv6Addr, A::V6>),
}
-impl AddrSubnetEither {
+impl<A: IpAddrWitness> AddrSubnetEither<A> {
/// Creates a new `AddrSubnetEither`.
///
/// `new` creates a new `AddrSubnetEither` with the given address and prefix
- /// length. The network address of the subnet is taken to be the first
- /// `prefix` bits of the address. It returns `None` if `prefix` is longer
- /// than the number of bits in this type of IP address (32 for IPv4 and 128
- /// for IPv6).
+ /// length. It returns `None` under the same conditions as
+ /// [`AddrSubnet::new`].
#[inline]
- pub fn new(addr: IpAddr, prefix: u8) -> Option<AddrSubnetEither> {
+ pub fn new(addr: IpAddr, prefix: u8) -> Option<AddrSubnetEither<A>> {
Some(match addr {
IpAddr::V4(addr) => AddrSubnetEither::V4(AddrSubnet::new(addr, prefix)?),
IpAddr::V6(addr) => AddrSubnetEither::V6(AddrSubnet::new(addr, prefix)?),
@@ -1097,7 +1130,7 @@
/// Gets the contained IP address and prefix in this `AddrSubnetEither`.
#[inline]
- pub fn into_addr_prefix(self) -> (SpecifiedAddr<IpAddr>, u8) {
+ pub fn into_addr_prefix(self) -> (A, u8) {
match self {
AddrSubnetEither::V4(v4) => (v4.addr.into(), v4.subnet.prefix),
AddrSubnetEither::V6(v6) => (v6.addr.into(), v6.subnet.prefix),
@@ -1106,7 +1139,7 @@
/// Gets the IP address and subnet in this `AddrSubnetEither`.
#[inline]
- pub fn into_addr_subnet(self) -> (SpecifiedAddr<IpAddr>, SubnetEither) {
+ pub fn into_addr_subnet(self) -> (A, SubnetEither) {
match self {
AddrSubnetEither::V4(v4) => (v4.addr.into(), SubnetEither::V4(v4.subnet)),
AddrSubnetEither::V6(v6) => (v6.addr.into(), SubnetEither::V6(v6.subnet)),
@@ -1179,30 +1212,42 @@
// Network address has more than top 8 bits set
assert_eq!(Subnet::new(Ipv4Addr::new([255, 255, 0, 0]), 8), None);
- AddrSubnet::new(Ipv4Addr::new([1, 2, 3, 4]), 32).unwrap();
+ AddrSubnet::<_, SpecifiedAddr<_>>::new(Ipv4Addr::new([1, 2, 3, 4]), 32).unwrap();
// The unspecified address is not considered to be a unicast address in
// any subnet (use assert, not assert_eq, because AddrSubnet doesn't
// impl Debug)
- assert!(AddrSubnet::new(Ipv4::UNSPECIFIED_ADDRESS, 16) == None);
- assert!(AddrSubnet::new(Ipv6::UNSPECIFIED_ADDRESS, 64) == None);
+ assert!(AddrSubnet::<_, SpecifiedAddr<_>>::new(Ipv4::UNSPECIFIED_ADDRESS, 16) == None);
+ assert!(AddrSubnet::<_, SpecifiedAddr<_>>::new(Ipv6::UNSPECIFIED_ADDRESS, 64) == None);
// Prefix exceeds 32/128 bits
- assert!(AddrSubnet::new(Ipv4Addr::new([1, 2, 3, 4]), 33) == None);
+ assert!(AddrSubnet::<_, SpecifiedAddr<_>>::new(Ipv4Addr::new([1, 2, 3, 4]), 33) == None);
assert!(
- AddrSubnet::new(
+ AddrSubnet::<_, SpecifiedAddr<_>>::new(
Ipv6Addr::new([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]),
129
) == None
);
// Global broadcast
- assert!(AddrSubnet::new(Ipv4::GLOBAL_BROADCAST_ADDRESS.into_addr(), 16) == None);
- // Subnet broadcast
- assert!(AddrSubnet::new(Ipv4Addr::new([192, 168, 255, 255]), 16) == None);
- // Multicast
- assert!(AddrSubnet::new(Ipv4Addr::new([224, 0, 0, 1]), 16) == None);
assert!(
- AddrSubnet::new(Ipv6Addr::new([0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]), 64)
+ AddrSubnet::<_, SpecifiedAddr<_>>::new(Ipv4::GLOBAL_BROADCAST_ADDRESS.into_addr(), 16)
== None
);
+ // Subnet broadcast
+ assert!(
+ AddrSubnet::<_, SpecifiedAddr<_>>::new(Ipv4Addr::new([192, 168, 255, 255]), 16) == None
+ );
+ // Multicast
+ assert!(AddrSubnet::<_, SpecifiedAddr<_>>::new(Ipv4Addr::new([224, 0, 0, 1]), 16) == None);
+ assert!(
+ AddrSubnet::<_, SpecifiedAddr<_>>::new(
+ Ipv6Addr::new([0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]),
+ 64
+ ) == None
+ );
+
+ // If we use the `LinkLocalAddr` witness type, then non link-local
+ // addresses are rejected. Note that this address was accepted above
+ // when `SpecifiedAddr` was used.
+ assert!(AddrSubnet::<_, LinkLocalAddr<_>>::new(Ipv4Addr::new([1, 2, 3, 4]), 32) == None);
}
#[test]
diff --git a/src/connectivity/lib/net-types/src/lib.rs b/src/connectivity/lib/net-types/src/lib.rs
index 2529784..b19c798 100644
--- a/src/connectivity/lib/net-types/src/lib.rs
+++ b/src/connectivity/lib/net-types/src/lib.rs
@@ -25,6 +25,28 @@
pub trait Sealed {}
}
+/// A type which is a witness to some property about an address.
+///
+/// A type which implements `Witness<A>` wraps an address of type `A` and
+/// guarantees some property about the wrapped address. It is implemented by
+/// [`SpecifiedAddr`], [`UnicastAddr`], [`MulticastAddr`], and
+/// [`LinkLocalAddr`].
+pub trait Witness<A>: Deref<Target = A> + sealed::Sealed + Sized {
+ /// Constructs a new witness type..
+ ///
+ /// `new` returns `None` if `addr` does not satisfy the property guaranteed
+ /// by `Self`.
+ fn new(addr: A) -> Option<Self>;
+
+ /// Get a clone of the address.
+ fn get(&self) -> A
+ where
+ A: Clone;
+
+ /// Consumes this witness and returns the contained `A`.
+ fn into_addr(self) -> A;
+}
+
// NOTE: The "witness" types UnicastAddr, MulticastAddr, and LinkLocalAddr -
// which provide the invariant that the value they contain is a unicast,
// multicast, or link-local address, respectively - cannot actually guarantee
@@ -172,6 +194,30 @@
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
pub struct SpecifiedAddr<A>(A);
+impl<A: SpecifiedAddress> sealed::Sealed for SpecifiedAddr<A> {}
+impl<A: SpecifiedAddress> Witness<A> for SpecifiedAddr<A> {
+ #[inline]
+ fn new(addr: A) -> Option<SpecifiedAddr<A>> {
+ if !addr.is_specified() {
+ return None;
+ }
+ Some(SpecifiedAddr(addr))
+ }
+
+ #[inline]
+ fn get(&self) -> A
+ where
+ A: Clone,
+ {
+ self.0.clone()
+ }
+
+ #[inline]
+ fn into_addr(self) -> A {
+ self.0
+ }
+}
+
impl<A> SpecifiedAddr<A> {
/// Constructs a new `SpecifiedAddr` without checking to see if `addr` is
/// actually a specified address.
@@ -185,34 +231,6 @@
pub const unsafe fn new_unchecked(addr: A) -> SpecifiedAddr<A> {
SpecifiedAddr(addr)
}
-
- /// Consumes this `SpecifiedAddr` and returns the contained `A`.
- #[inline]
- pub fn into_addr(self) -> A {
- self.0
- }
-}
-
-impl<A: SpecifiedAddress> SpecifiedAddr<A> {
- /// Constructs a new `SpecifiedAddr`.
- ///
- /// `new` returns `None` if `addr` is not a specified address according to
- /// [`SpecifiedAddress::is_specified`].
- #[inline]
- pub fn new(addr: A) -> Option<SpecifiedAddr<A>> {
- if !addr.is_specified() {
- return None;
- }
- Some(SpecifiedAddr(addr))
- }
-}
-
-impl<A: Clone> SpecifiedAddr<A> {
- /// Get a clone of the address.
- #[inline]
- pub fn get(&self) -> A {
- self.0.clone()
- }
}
impl<A: SpecifiedAddress> Deref for SpecifiedAddr<A> {
@@ -240,6 +258,30 @@
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
pub struct UnicastAddr<A>(A);
+impl<A: UnicastAddress> sealed::Sealed for UnicastAddr<A> {}
+impl<A: UnicastAddress> Witness<A> for UnicastAddr<A> {
+ #[inline]
+ fn new(addr: A) -> Option<UnicastAddr<A>> {
+ if !addr.is_unicast() {
+ return None;
+ }
+ Some(UnicastAddr(addr))
+ }
+
+ #[inline]
+ fn get(&self) -> A
+ where
+ A: Clone,
+ {
+ self.0.clone()
+ }
+
+ #[inline]
+ fn into_addr(self) -> A {
+ self.0
+ }
+}
+
impl<A> UnicastAddr<A> {
/// Constructs a new `UnicastAddr` without checking to see if `addr` is
/// actually a unicast address.
@@ -253,34 +295,6 @@
pub const unsafe fn new_unchecked(addr: A) -> UnicastAddr<A> {
UnicastAddr(addr)
}
-
- /// Consumes this `UnicastAddr` and returns the contained `A`.
- #[inline]
- pub fn into_addr(self) -> A {
- self.0
- }
-}
-
-impl<A: UnicastAddress> UnicastAddr<A> {
- /// Constructs a new `UnicastAddr`.
- ///
- /// `new` returns `None` if `addr` is not a unicast address according to
- /// [`UnicastAddress::is_unicast`].
- #[inline]
- pub fn new(addr: A) -> Option<UnicastAddr<A>> {
- if !addr.is_unicast() {
- return None;
- }
- Some(UnicastAddr(addr))
- }
-}
-
-impl<A: Clone> UnicastAddr<A> {
- /// Get a clone of the address.
- #[inline]
- pub fn get(&self) -> A {
- self.0.clone()
- }
}
impl<A: UnicastAddress> Deref for UnicastAddr<A> {
@@ -308,6 +322,30 @@
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
pub struct MulticastAddr<A>(A);
+impl<A: MulticastAddress> sealed::Sealed for MulticastAddr<A> {}
+impl<A: MulticastAddress> Witness<A> for MulticastAddr<A> {
+ #[inline]
+ fn new(addr: A) -> Option<MulticastAddr<A>> {
+ if !addr.is_multicast() {
+ return None;
+ }
+ Some(MulticastAddr(addr))
+ }
+
+ #[inline]
+ fn get(&self) -> A
+ where
+ A: Clone,
+ {
+ self.0.clone()
+ }
+
+ #[inline]
+ fn into_addr(self) -> A {
+ self.0
+ }
+}
+
impl<A> MulticastAddr<A> {
/// Construct a new `MulticastAddr` without checking to see if `addr` is
/// actually a multicast address.
@@ -321,12 +359,6 @@
pub const unsafe fn new_unchecked(addr: A) -> MulticastAddr<A> {
MulticastAddr(addr)
}
-
- /// Consumes this `MulticastAddr` and returns the contained `A`.
- #[inline]
- pub fn into_addr(self) -> A {
- self.0
- }
}
impl<A: SpecifiedAddress> MulticastAddr<A> {
@@ -341,28 +373,6 @@
}
}
-impl<A: MulticastAddress> MulticastAddr<A> {
- /// Constructs a new `MulticastAddr`.
- ///
- /// `new` returns `None` if `addr` is not a multicast address according to
- /// [`MulticastAddress::is_multicast`].
- #[inline]
- pub fn new(addr: A) -> Option<MulticastAddr<A>> {
- if !addr.is_multicast() {
- return None;
- }
- Some(MulticastAddr(addr))
- }
-}
-
-impl<A: Clone> MulticastAddr<A> {
- /// Get a clone of the address.
- #[inline]
- pub fn get(&self) -> A {
- self.0.clone()
- }
-}
-
impl<A: MulticastAddress> Deref for MulticastAddr<A> {
type Target = A;
@@ -394,6 +404,30 @@
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
pub struct LinkLocalAddr<A>(A);
+impl<A: LinkLocalAddress> sealed::Sealed for LinkLocalAddr<A> {}
+impl<A: LinkLocalAddress> Witness<A> for LinkLocalAddr<A> {
+ #[inline]
+ fn new(addr: A) -> Option<LinkLocalAddr<A>> {
+ if !addr.is_linklocal() {
+ return None;
+ }
+ Some(LinkLocalAddr(addr))
+ }
+
+ #[inline]
+ fn get(&self) -> A
+ where
+ A: Clone,
+ {
+ self.0.clone()
+ }
+
+ #[inline]
+ fn into_addr(self) -> A {
+ self.0
+ }
+}
+
impl<A> LinkLocalAddr<A> {
/// Construct a new `LinkLocalAddr` without checking to see if `addr` is
/// actually a link-local address.
@@ -407,12 +441,6 @@
pub const unsafe fn new_unchecked(addr: A) -> LinkLocalAddr<A> {
LinkLocalAddr(addr)
}
-
- /// Consumes this `LinkLocalAddr` and returns the contained `A`.
- #[inline]
- pub fn into_addr(self) -> A {
- self.0
- }
}
impl<A: SpecifiedAddress> LinkLocalAddr<A> {
@@ -427,28 +455,6 @@
}
}
-impl<A: LinkLocalAddress> LinkLocalAddr<A> {
- /// Constructs a new `LinkLocalAddr`.
- ///
- /// `new` returns `None` if `addr` is not a link-local address according to
- /// [`LinkLocalAddress::is_linklocal`].
- #[inline]
- pub fn new(addr: A) -> Option<LinkLocalAddr<A>> {
- if !addr.is_linklocal() {
- return None;
- }
- Some(LinkLocalAddr(addr))
- }
-}
-
-impl<A: Clone> LinkLocalAddr<A> {
- /// Get a clone of the address.
- #[inline]
- pub fn get(&self) -> A {
- self.0.clone()
- }
-}
-
impl<A: LinkLocalAddress> Deref for LinkLocalAddr<A> {
type Target = A;
diff --git a/src/connectivity/network/netstack3/core/src/device/ethernet.rs b/src/connectivity/network/netstack3/core/src/device/ethernet.rs
index 958b244..aca86b0 100644
--- a/src/connectivity/network/netstack3/core/src/device/ethernet.rs
+++ b/src/connectivity/network/netstack3/core/src/device/ethernet.rs
@@ -13,7 +13,8 @@
use net_types::ethernet::Mac;
use net_types::ip::{AddrSubnet, Ip, IpAddr, IpAddress, Ipv4, Ipv4Addr, Ipv6, Ipv6Addr};
use net_types::{
- BroadcastAddress, LinkLocalAddr, MulticastAddr, MulticastAddress, SpecifiedAddr, UnicastAddress,
+ BroadcastAddress, LinkLocalAddr, MulticastAddr, MulticastAddress, SpecifiedAddr,
+ UnicastAddress, Witness,
};
use packet::{Buf, BufferMut, EmptyBuf, Nested, Serializer};
use specialize_ip_macro::{specialize_ip, specialize_ip_address};
diff --git a/src/connectivity/network/netstack3/core/src/device/mod.rs b/src/connectivity/network/netstack3/core/src/device/mod.rs
index cb3bc68..5667f7e 100644
--- a/src/connectivity/network/netstack3/core/src/device/mod.rs
+++ b/src/connectivity/network/netstack3/core/src/device/mod.rs
@@ -14,7 +14,7 @@
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};
+use net_types::{LinkLocalAddr, MulticastAddr, SpecifiedAddr, Witness};
use packet::{BufferMut, Serializer};
use specialize_ip_macro::specialize_ip;
diff --git a/src/connectivity/network/netstack3/core/src/device/ndp.rs b/src/connectivity/network/netstack3/core/src/device/ndp.rs
index f59d752b..6de1ee0 100644
--- a/src/connectivity/network/netstack3/core/src/device/ndp.rs
+++ b/src/connectivity/network/netstack3/core/src/device/ndp.rs
@@ -29,7 +29,7 @@
use net_types::ip::{AddrSubnet, Ip, Ipv6, Ipv6Addr};
use net_types::{
LinkLocalAddr, LinkLocalAddress, MulticastAddr, MulticastAddress, SpecifiedAddr,
- SpecifiedAddress,
+ SpecifiedAddress, Witness,
};
use packet::{EmptyBuf, InnerPacketBuilder, Serializer};
use rand::{thread_rng, Rng};
diff --git a/src/connectivity/network/netstack3/core/src/ip/icmp.rs b/src/connectivity/network/netstack3/core/src/ip/icmp.rs
index 8c92cc1..a1907d4 100644
--- a/src/connectivity/network/netstack3/core/src/ip/icmp.rs
+++ b/src/connectivity/network/netstack3/core/src/ip/icmp.rs
@@ -7,7 +7,7 @@
use byteorder::{ByteOrder, NetworkEndian};
use log::{debug, trace};
use net_types::ip::{Ip, IpAddress, Ipv4, Ipv4Addr, Ipv6, Ipv6Addr};
-use net_types::{MulticastAddress, SpecifiedAddr};
+use net_types::{MulticastAddress, SpecifiedAddr, Witness};
use packet::{BufferMut, Serializer, TruncateDirection, TruncatingSerializer};
use specialize_ip_macro::specialize_ip_address;
diff --git a/src/connectivity/network/netstack3/core/src/ip/igmp.rs b/src/connectivity/network/netstack3/core/src/ip/igmp.rs
index f82390c..2ee5c5c 100644
--- a/src/connectivity/network/netstack3/core/src/ip/igmp.rs
+++ b/src/connectivity/network/netstack3/core/src/ip/igmp.rs
@@ -14,7 +14,7 @@
use failure::Fail;
use log::{debug, error};
use net_types::ip::{AddrSubnet, Ipv4Addr};
-use net_types::{MulticastAddr, SpecifiedAddr, SpecifiedAddress};
+use net_types::{MulticastAddr, SpecifiedAddr, SpecifiedAddress, Witness};
use packet::{BufferMut, EmptyBuf, InnerPacketBuilder};
use rand::Rng;
use rand_xorshift::XorShiftRng;
diff --git a/src/connectivity/network/netstack3/core/src/ip/mld.rs b/src/connectivity/network/netstack3/core/src/ip/mld.rs
index 39f8801..adf7db0 100644
--- a/src/connectivity/network/netstack3/core/src/ip/mld.rs
+++ b/src/connectivity/network/netstack3/core/src/ip/mld.rs
@@ -14,7 +14,7 @@
use failure::Fail;
use log::{debug, error};
use net_types::ip::{Ip, Ipv6, Ipv6Addr};
-use net_types::{LinkLocalAddr, MulticastAddr, SpecifiedAddr, SpecifiedAddress};
+use net_types::{LinkLocalAddr, MulticastAddr, SpecifiedAddr, SpecifiedAddress, Witness};
use packet::serialize::Serializer;
use packet::{EmptyBuf, InnerPacketBuilder};
use rand::Rng;
diff --git a/src/connectivity/network/netstack3/core/src/ip/mod.rs b/src/connectivity/network/netstack3/core/src/ip/mod.rs
index 22ffec3..82f8539 100644
--- a/src/connectivity/network/netstack3/core/src/ip/mod.rs
+++ b/src/connectivity/network/netstack3/core/src/ip/mod.rs
@@ -24,7 +24,7 @@
use log::{debug, trace};
use net_types::ip::{AddrSubnet, Ip, IpAddress, IpVersion, Ipv4, Ipv4Addr, Ipv6, Ipv6Addr, Subnet};
-use net_types::{LinkLocalAddr, MulticastAddr, SpecifiedAddr};
+use net_types::{LinkLocalAddr, MulticastAddr, SpecifiedAddr, Witness};
use packet::{Buf, BufferMut, Either, EmptyBuf, ParseMetadata, Serializer};
use specialize_ip_macro::{specialize_ip, specialize_ip_address};
diff --git a/src/connectivity/network/netstack3/core/src/ip/path_mtu.rs b/src/connectivity/network/netstack3/core/src/ip/path_mtu.rs
index fdddf4f..1b4de6d 100644
--- a/src/connectivity/network/netstack3/core/src/ip/path_mtu.rs
+++ b/src/connectivity/network/netstack3/core/src/ip/path_mtu.rs
@@ -406,7 +406,7 @@
use super::*;
use net_types::ip::{Ipv4, Ipv6};
- use net_types::SpecifiedAddr;
+ use net_types::{SpecifiedAddr, Witness};
use specialize_ip_macro::specialize_ip_address;
use crate::testutil::{
diff --git a/src/connectivity/network/netstack3/core/src/ip/reassembly.rs b/src/connectivity/network/netstack3/core/src/ip/reassembly.rs
index 2e765ed..c561f84 100644
--- a/src/connectivity/network/netstack3/core/src/ip/reassembly.rs
+++ b/src/connectivity/network/netstack3/core/src/ip/reassembly.rs
@@ -722,6 +722,7 @@
#[cfg(test)]
mod tests {
use net_types::ip::{IpAddress, Ipv4, Ipv6};
+ use net_types::Witness;
use packet::{Buf, ParseBuffer, Serializer};
use specialize_ip_macro::specialize_ip;
diff --git a/src/connectivity/network/netstack3/core/src/ip/types.rs b/src/connectivity/network/netstack3/core/src/ip/types.rs
index a89cb94..d416f7f 100644
--- a/src/connectivity/network/netstack3/core/src/ip/types.rs
+++ b/src/connectivity/network/netstack3/core/src/ip/types.rs
@@ -367,6 +367,8 @@
#[cfg(test)]
mod tests {
+ use net_types::Witness;
+
use super::*;
#[test]
diff --git a/src/connectivity/network/netstack3/core/src/testutil.rs b/src/connectivity/network/netstack3/core/src/testutil.rs
index 4632cda..46b69c95 100644
--- a/src/connectivity/network/netstack3/core/src/testutil.rs
+++ b/src/connectivity/network/netstack3/core/src/testutil.rs
@@ -16,7 +16,7 @@
use log::{debug, trace};
use net_types::ethernet::Mac;
use net_types::ip::{AddrSubnet, Ip, IpAddr, IpAddress, Ipv4Addr, Ipv6Addr, Subnet, SubnetEither};
-use net_types::SpecifiedAddr;
+use net_types::{SpecifiedAddr, Witness};
use packet::{Buf, BufferMut, ParsablePacket, ParseBuffer, Serializer};
use rand::{self, CryptoRng, RngCore, SeedableRng};
use rand_xorshift::XorShiftRng;
diff --git a/src/connectivity/network/netstack3/core/src/transport/udp.rs b/src/connectivity/network/netstack3/core/src/transport/udp.rs
index 0491c25..2be5b30 100644
--- a/src/connectivity/network/netstack3/core/src/transport/udp.rs
+++ b/src/connectivity/network/netstack3/core/src/transport/udp.rs
@@ -7,7 +7,7 @@
use std::num::NonZeroU16;
use net_types::ip::{Ip, IpAddress};
-use net_types::SpecifiedAddr;
+use net_types::{SpecifiedAddr, Witness};
use packet::{BufferMut, ParsablePacket, Serializer};
use specialize_ip_macro::specialize_ip;
use zerocopy::ByteSlice;
diff --git a/src/connectivity/network/netstack3/core/src/wire/icmp/mld.rs b/src/connectivity/network/netstack3/core/src/wire/icmp/mld.rs
index 00274c6..a63bf6f 100644
--- a/src/connectivity/network/netstack3/core/src/wire/icmp/mld.rs
+++ b/src/connectivity/network/netstack3/core/src/wire/icmp/mld.rs
@@ -240,6 +240,7 @@
#[cfg(test)]
mod tests {
+ use net_types::Witness;
use packet::{InnerPacketBuilder, ParseBuffer, Serializer};
use std::convert::TryInto;
use std::fmt::Debug;
diff --git a/src/connectivity/network/netstack3/src/eventloop/integration_tests.rs b/src/connectivity/network/netstack3/src/eventloop/integration_tests.rs
index c54c255..8415886 100644
--- a/src/connectivity/network/netstack3/src/eventloop/integration_tests.rs
+++ b/src/connectivity/network/netstack3/src/eventloop/integration_tests.rs
@@ -11,7 +11,7 @@
use fuchsia_component::client;
use futures::{future, Future, FutureExt, StreamExt};
use net_types::ip::{AddrSubnetEither, IpAddr, Ipv4, Ipv4Addr};
-use net_types::SpecifiedAddr;
+use net_types::{SpecifiedAddr, Witness};
use netstack3_core::icmp::{self as core_icmp, IcmpConnId};
use packet::Buf;
use pin_utils::pin_mut;
diff --git a/src/connectivity/network/netstack3/src/eventloop/util.rs b/src/connectivity/network/netstack3/src/eventloop/util.rs
index a21b388..3891ad0 100644
--- a/src/connectivity/network/netstack3/src/eventloop/util.rs
+++ b/src/connectivity/network/netstack3/src/eventloop/util.rs
@@ -5,7 +5,7 @@
use fidl_fuchsia_net as fidl_net;
use fidl_fuchsia_net_stack as fidl_net_stack;
use net_types::ip::{AddrSubnetEither, IpAddr, Ipv4Addr, Ipv6Addr, SubnetEither};
-use net_types::SpecifiedAddr;
+use net_types::{SpecifiedAddr, Witness};
use netstack3_core::{Context, DeviceId, EntryDest, EntryDestEither, EntryEither};
use never::Never;
use std::convert::TryFrom;