Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[sled-agent] Allocate VNICs over etherstubs, fix inter-zone routing #1066

Merged
merged 18 commits into from
Jun 1, 2022
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 13 additions & 9 deletions sled-agent/src/bootstrap/agent.rs
Original file line number Diff line number Diff line change
Expand Up @@ -138,19 +138,23 @@ impl Agent {
"server" => sled_config.id.to_string(),
));

let data_link = if let Some(link) = sled_config.data_link.clone() {
link
} else {
Dladm::find_physical().map_err(|err| {
let etherstub = Dladm::create_etherstub().map_err(|e| {
BootstrapError::SledError(format!(
"Can't access etherstub device: {}",
e
))
})?;

let etherstub_vnic =
Dladm::create_etherstub_vnic(&etherstub).map_err(|e| {
BootstrapError::SledError(format!(
"Can't access physical link, and none in config: {}",
err
"Can't access etherstub VNIC device: {}",
e
))
})?
};
})?;

Zones::ensure_has_global_zone_v6_address(
data_link,
etherstub_vnic,
address,
"bootstrap6",
)
Expand Down
2 changes: 1 addition & 1 deletion sled-agent/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ pub struct Config {
/// Optional list of zpools to be used as "discovered disks".
pub zpools: Option<Vec<ZpoolName>>,

/// The data link on which to allocate VNICs.
/// The data link on which we infer the bootstrap address.
///
/// If unsupplied, we default to the first physical device.
pub data_link: Option<PhysicalLink>,
Expand Down
79 changes: 74 additions & 5 deletions sled-agent/src/illumos/dladm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ pub const VNIC_PREFIX_GUEST: &str = "vopte";

pub const DLADM: &str = "/usr/sbin/dladm";

pub const ETHERSTUB_NAME: &str = "stub0";
pub const ETHERSTUB_VNIC_NAME: &str = "underlay0";

/// Errors returned from [`Dladm::find_physical`].
#[derive(thiserror::Error, Debug)]
pub enum FindPhysicalLinkError {
Expand Down Expand Up @@ -49,7 +52,7 @@ pub enum GetMacError {
#[error("Failed to create VNIC {name} on link {link:?}: {err}")]
pub struct CreateVnicError {
name: String,
link: PhysicalLink,
link: String,
#[source]
err: ExecutionError,
}
Expand All @@ -75,11 +78,77 @@ pub struct DeleteVnicError {
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq)]
pub struct PhysicalLink(pub String);

/// The name of an etherstub
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq)]
pub struct Etherstub(pub String);

/// The name of an etherstub's underlay VNIC
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq)]
pub struct EtherstubVnic(pub String);

/// Identifies that an object may be used to create a VNIC.
pub trait VnicSource {
fn name(&self) -> &str;
}

impl VnicSource for Etherstub {
fn name(&self) -> &str {
&self.0
}
}

impl VnicSource for PhysicalLink {
fn name(&self) -> &str {
&self.0
}
}

/// Wraps commands for interacting with data links.
pub struct Dladm {}

#[cfg_attr(test, mockall::automock, allow(dead_code))]
impl Dladm {
/// Creates an etherstub, or returns one which already exists.
pub fn create_etherstub() -> Result<Etherstub, ExecutionError> {
if let Ok(stub) = Self::get_etherstub() {
return Ok(stub);
}
let mut command = std::process::Command::new(PFEXEC);
let cmd =
command.args(&[DLADM, "create-etherstub", "-t", ETHERSTUB_NAME]);
rcgoodfellow marked this conversation as resolved.
Show resolved Hide resolved
execute(cmd)?;
Ok(Etherstub(ETHERSTUB_NAME.to_string()))
}

/// Finds an etherstub.
fn get_etherstub() -> Result<Etherstub, ExecutionError> {
let mut command = std::process::Command::new(PFEXEC);
let cmd = command.args(&[DLADM, "show-etherstub", ETHERSTUB_NAME]);
execute(cmd)?;
Ok(Etherstub(ETHERSTUB_NAME.to_string()))
}

/// Creates a VNIC on top of the etherstub.
///
/// This VNIC is not tracked like [`crate::illumos::vnic::Vnic`], because
/// it is expected to exist for the lifetime of the sled.
pub fn create_etherstub_vnic(
source: &Etherstub,
) -> Result<EtherstubVnic, CreateVnicError> {
if let Ok(vnic) = Self::get_etherstub_vnic() {
return Ok(vnic);
}
Self::create_vnic(source, ETHERSTUB_VNIC_NAME, None, None)?;
Ok(EtherstubVnic(ETHERSTUB_VNIC_NAME.to_string()))
}

fn get_etherstub_vnic() -> Result<EtherstubVnic, ExecutionError> {
let mut command = std::process::Command::new(PFEXEC);
let cmd = command.args(&[DLADM, "show-vnic", ETHERSTUB_VNIC_NAME]);
execute(cmd)?;
Ok(EtherstubVnic(ETHERSTUB_VNIC_NAME.to_string()))
}

/// Returns the name of the first observed physical data link.
pub fn find_physical() -> Result<PhysicalLink, FindPhysicalLinkError> {
let mut command = std::process::Command::new(PFEXEC);
Expand Down Expand Up @@ -135,8 +204,8 @@ impl Dladm {
/// * `vnic_name`: Exact name of the VNIC to be created.
/// * `mac`: An optional unicast MAC address for the newly created NIC.
/// * `vlan`: An optional VLAN ID for VLAN tagging.
pub fn create_vnic(
physical: &PhysicalLink,
pub fn create_vnic<T: VnicSource + 'static>(
source: &T,
vnic_name: &str,
mac: Option<MacAddr>,
vlan: Option<VlanID>,
Expand All @@ -147,7 +216,7 @@ impl Dladm {
"create-vnic".to_string(),
"-t".to_string(),
"-l".to_string(),
physical.0.to_string(),
source.name().to_string(),
];

if let Some(mac) = mac {
Expand All @@ -164,7 +233,7 @@ impl Dladm {
let cmd = command.args(&args);
execute(cmd).map_err(|err| CreateVnicError {
name: vnic_name.to_string(),
link: physical.clone(),
link: source.name().to_string(),
err,
})?;
Ok(())
Expand Down
12 changes: 6 additions & 6 deletions sled-agent/src/illumos/vnic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
//! API for controlling a single instance.

use crate::illumos::dladm::{
CreateVnicError, DeleteVnicError, PhysicalLink, VNIC_PREFIX,
CreateVnicError, DeleteVnicError, Etherstub, VNIC_PREFIX,
VNIC_PREFIX_CONTROL, VNIC_PREFIX_GUEST,
};
use omicron_common::api::external::MacAddr;
Expand All @@ -26,7 +26,7 @@ use crate::illumos::dladm::MockDladm as Dladm;
pub struct VnicAllocator {
value: Arc<AtomicU64>,
scope: String,
data_link: PhysicalLink,
data_link: Etherstub,
}

impl VnicAllocator {
Expand All @@ -41,11 +41,11 @@ impl VnicAllocator {
///
/// VnicAllocator::new("Storage") produces
/// - oxControlStorage[NNN]
pub fn new<S: AsRef<str>>(scope: S, physical_link: PhysicalLink) -> Self {
pub fn new<S: AsRef<str>>(scope: S, etherstub: Etherstub) -> Self {
Self {
value: Arc::new(AtomicU64::new(0)),
scope: scope.as_ref().to_string(),
data_link: physical_link,
data_link: etherstub,
}
}

Expand Down Expand Up @@ -171,7 +171,7 @@ mod test {
#[test]
fn test_allocate() {
let allocator =
VnicAllocator::new("Foo", PhysicalLink("mylink".to_string()));
VnicAllocator::new("Foo", Etherstub("mystub".to_string()));
assert_eq!("oxFoo0", allocator.next());
assert_eq!("oxFoo1", allocator.next());
assert_eq!("oxFoo2", allocator.next());
Expand All @@ -180,7 +180,7 @@ mod test {
#[test]
fn test_allocate_within_scopes() {
let allocator =
VnicAllocator::new("Foo", PhysicalLink("mylink".to_string()));
VnicAllocator::new("Foo", Etherstub("mystub".to_string()));
assert_eq!("oxFoo0", allocator.next());
let allocator = allocator.new_superscope("Baz");
assert_eq!("oxBazFoo1", allocator.next());
Expand Down
11 changes: 6 additions & 5 deletions sled-agent/src/illumos/zone.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,10 @@ use slog::Logger;
use std::net::{IpAddr, Ipv6Addr};

use crate::illumos::addrobj::AddrObject;
use crate::illumos::dladm::{PhysicalLink, VNIC_PREFIX_CONTROL};
use crate::illumos::dladm::{EtherstubVnic, VNIC_PREFIX_CONTROL};
use crate::illumos::zfs::ZONE_ZFS_DATASET_MOUNTPOINT;
use crate::illumos::{execute, PFEXEC};
use omicron_common::address::AZ_PREFIX;

const DLADM: &str = "/usr/sbin/dladm";
const IPADM: &str = "/usr/sbin/ipadm";
Expand Down Expand Up @@ -101,7 +102,7 @@ pub struct EnsureAddressError {
#[error("Failed to create address {address} with name {name} in the GZ on {link:?}: {err}")]
pub struct EnsureGzAddressError {
address: Ipv6Addr,
link: PhysicalLink,
link: EtherstubVnic,
name: String,
#[source]
err: anyhow::Error,
Expand All @@ -122,7 +123,7 @@ impl AddressRequest {
pub fn new_static(ip: IpAddr, prefix: Option<u8>) -> Self {
let prefix = prefix.unwrap_or_else(|| match ip {
IpAddr::V4(_) => 24,
IpAddr::V6(_) => 64,
IpAddr::V6(_) => AZ_PREFIX,
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This ended up being a major aspect of this patch - without it, I could ping all /64 addresses between GZ / non-GZ zones, but not the DNS addresses.

However, by opening it up to the AZ prefix, I can also communicate between arbitrary "sled-local" services and the internal-dns server, which resides outside the sled's /64.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can see how we need that, but I'm not entirely sure it's how we want to solve the problem of routing to the DNS server. IIUC, you're saying that the sled agent's VNICs for Oxide services (sled agent, nexus, propolis, etc) are now things like: fd00:1122:3344:101:/48. What does the sled's /64 prefix mean in this setup? I think @rcgoodfellow or @rmustacc should probably weigh in here, since it seems to me to kinda be skirting the real meaning of that prefix.

I think one option would be to add a separate route which specifies the DNS server's address / prefix. I believe DDM will ultimately be manipulating the OS's routing tables so that's actually true. But that may not be enough, in that traffic from the VNIC also needs a route pointing it to an interface for the DNS address. I don't know enough to be sure here.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For context, this is what my global zone looks like:

// Note, basically all `/64`
$ ipadm
...
underlay0/linklocal addrconf ok         fe80::8:20ff:fea6:3b8/10
underlay0/bootstrap6 static ok          fdb0:18c0:4d0c:f4e5::1/64
underlay0/sled6   static   ok           fd00:1122:3344:101::1/64
underlay0/internaldns static ok         fd00:1122:3344:1::2/64

Meanwhile, in Nexus (non-global zone):

// Note, this is where the `/48` shows up - it's the AZ_PREFIX.
# ipadm
...
oxControlService1/linklocal addrconf ok fe80::8:20ff:fe35:d2a5/10
oxControlService1/omicron6 static ok    fd00:1122:3344:101::3/48

This /48 specifically alters the routing within the non-global zone - netstat -rn -f inet6 in Nexus shows the following:

Routing Table: IPv6
  Destination/Mask            Gateway                   Flags Ref   Use    If   
--------------------------- --------------------------- ----- --- ------- ----- 
::1                         ::1                         UH      2       0 lo0   
fd00:1122:3344::/48         fd00:1122:3344:101::3       U       6    2259 oxControlService1 
fe80::/10                   fe80::8:20ff:fe35:d2a5      U       2       0 oxControlService1

Having all traffic destined for the AZ routed through the interface is the piece I really care about here.

Do you think it would be preferable to:

  • Continue allocating addresses within non-global zones as /64
  • Call route to manually add this path to the AZ subnet?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for those details. I think that is what I expected, that we'd have a route entry that says "anything in fd00:1122:3344::/48 should go out the VNIC oxControlService1". The part I'm wondering about is, that would imply that the netstack would expect that it could use that interface for any traffic from the Nexus zone for any other sled. As I write this, I realize that may be fine. If Nexus is trying to reach another service on the same sled, that packet will go out the VNIC, to the etherstub, and then presumably to the other zone's VNIC. If it's trying to reach something off the sled, I'm less sure of what'll happen there. It looks like it'll still go to the zone VNIC, the etherstub, and then to whatever route you have in the GZ that matches that (if one exists).

I think this is probably fine. It also seems to be working for a single machine, and it's easy enough to update this if we find it doesn't work for multiple machines.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you think it would be preferable to:

  • Continue allocating addresses within non-global zones as /64
  • Call route to manually add this path to the AZ subnet?

I've verified that this method works too - I'm seeing routing between zones by using:

route add -inet6 <address>/48 <address> -interface

When setting up a non-GZ address

Copy link
Collaborator Author

@smklein smklein May 18, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't the point of the default route that "if the destination address doesn't match the other rules, it should use this gateway"?

I tried your suggestion, but this doesn't seem to be working for me:

root@oxz_nexus:~# pfexec route add -inet6 fd00:1122:3344:1::1 fd00:1122:3344:101::3
add host fd00:1122:3344:1::1: gateway fd00:1122:3344:101::3: Network is unreachable

// Also does not not work with the `/48` in the destination
root@oxz_nexus:~# pfexec route add -inet6 fd00:1122:3344:1::1/48 -inet6 fd00:1122:3344:101::3
add net fd00:1122:3344:1::1/48: gateway fd00:1122:3344:101::3: Network is unreachable

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Chatting out-of-band with @bnaecker a bit: By issuing the following in the GZ:

routeadm -e ipv6-forwarding
routeadm -u

I'm seeing the routing make the extra hop, from NGZ -> GZ (and now) -> NGZ

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's true, I explained that very poorly. I was trying to point out that this command:

root@oxz_nexus:~# pfexec route add -inet6 default -inet6 fd00:1122:3344:101::1

isn't what I'd expect. In particular, that says for any traffic without a more specific route, send it to the gateway fd00:1122:3344:101::1. But that's not a gateway that the nexus zone has! The netstat -rn output shows the gateway we need as fd00:1122:3344:101::3.

But in any case, Robert pointed out that these routing tables are necessary but not sufficient to get this all to work. Specifically, we need to tell the GZ to actually act as a router, forwarding packets between different networks. That is, we've provided rules (assuming we can figure out how to express them 😆 ) for the routing daemon to use when forwarding packets, but it'll only do so if it's explicitly told it should.

I believe this can be accomplished with the command routeadm -e ipv6-forwarding -u, which enables route forwarding and restarts the SMF service(s) necessary to make that apply to the running system. IIUC, at that point, when the GZ networking stack receives a packet from the nexus zone, with an IP address of the (non-global) DNS zone, it'll attempt to forward that, by consulting the routing table.

I'm hypothesizing, but it seems like we need two routes then:

  • A route that tells the nexus zone to use it's VNIC's address as the gateway for DNS traffic
  • A route that tells the GZ how to reach the DNS zone's addresses

The former could be a default route, or a more constrained one listing the prefix for the DNS server. It seems like either should work, as long as the gateway is the IP address of the VNIC in the nexus zone, in this case fd00:1122:3344:101::3.

The latter can be accomplished by adding a route table that directs all the DNS traffic to the GZ's VNIC, I think. My understanding is that this would go onto the GZ VNIC, to the etherstub, and then forwarded to the non-global DNS zone VNIC.

I was initially confused as to why the "virtual switch" that man dladm describes under the create-etherstub command doesn't transparently do this. All the traffic is within that etherstub, and I'd have expected neighbor discovery and thus routing to be done automatically. So why do we need this?

The key is that the DNS addresses are in a different subnet. The etherstub will transparently create routes between all the other non-global zones, but once you're trying to reach an address in a different subnet, that has to involve routing. This explains why the -interface flag worked initially, too. That's effectively telling the etherstub that the other subnet can actually be routed to through the same L2 domain, even though it's on a different L3 subnet.

Robert pointed out that we may actually want a separate etherstub for the DNS zone. That'd more closely model the actual network we're emulating. In particular, we're trying to say that the GZ and all the non-DNS service zones are one little subnet, in the sled's /64. The DNS service is explicitly in a separate /64, for route summarization and the fact that it really is supposed to be a rack-wide or AZ-wide service.

To be clear, we should not add an additional etherstub in this PR. I think that's where we want to go longer-term, but we can defer it for sure.

So summarizing everything. When nexus wants to send a packet to the DNS server, that'll first go to the etherstub. The etherstub will not explicitly have a gateway for that, since it's in another subnet. It'll deliver it to the GZ. At that point, the IP stack in the GZ will take the packet and also note that it doesn't have that address. It'll instead consult the routing tables (assuming forwarding is enabled), and note that it can send that...back to the etherstub! That'll then go to the DNZ zone.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe the following will work, which summarizes the above conversation in part, and also makes a few simplifications.

image

I've tested this out on a fresh VM by creating the zones and doing all the plumbing and things appear to work. Here is what the setup looks like live. It does still require routeadm -e ipv6-forwarding -u in the GZ.

GZ

root@sled# ipadm
ADDROBJ           TYPE     STATE        ADDR
lo0/v4            static   ok           127.0.0.1/8
vioif0/v6         dhcp     ok           10.47.0.83/24
lo0/v6            static   ok           ::1/128
vnic0/v6          addrconf ok           fe80::8:20ff:fefc:a943/10
vnic0/omicron     static   ok           fd00:1122:3344:101::1/64
vnic0/dns         static   ok           fd00:1122:3344:1::2/64
root@sled# netstat -nr -f inet6

Routing Table: IPv6
  Destination/Mask            Gateway                   Flags Ref   Use    If
--------------------------- --------------------------- ----- --- ------- -----
::1                         ::1                         UH      2      20 lo0
fd00:1122:3344:1::/64       fd00:1122:3344:1::2         U       3      16 vnic0
fd00:1122:3344:101::/64     fd00:1122:3344:101::1       U       3      11 vnic0
fe80::/10                   fe80::8:20ff:fefc:a943      U       2       0 vnic0

Ping the Omicron zone

root@han:/opt/cargo-bay# ping fd00:1122:3344:101::3
fd00:1122:3344:101::3 is alive

Ping the DNS zone

root@han:/opt/cargo-bay# ping fd00:1122:3344:1::1
fd00:1122:3344:1::1 is alive

DNS Zone

root@dns:~# ipadm
ADDROBJ           TYPE     STATE        ADDR
lo0/v4            static   ok           127.0.0.1/8
lo0/v6            static   ok           ::1/128
vnic1/v6          addrconf ok           fe80::8:20ff:fe6a:2b/10
vnic1/underlay    static   ok           fd00:1122:3344:1::1/64
root@dns:~# netstat -nr -f inet6

Routing Table: IPv6
  Destination/Mask            Gateway                   Flags Ref   Use    If
--------------------------- --------------------------- ----- --- ------- -----
::1                         ::1                         UH      2       0 lo0
fd00:1122:3344:1::/64       fd00:1122:3344:1::1         U       3       7 vnic1
fd00:1122:3344::/48         fd00:1122:3344:1::2         UG      2       3
fe80::/10                   fe80::8:20ff:fe6a:2b        U       2       0 vnic1

Ping the Omicron zone

root@dns:~# ping fd00:1122:3344:101::3
ICMPv6 redirect from gateway fe80::8:20ff:fefc:a943
 to fd00:1122:3344:101::3 for fd00:1122:3344:101::3
fd00:1122:3344:101::3 is alive

Omicron Zone

root@omicron:~# ipadm
ADDROBJ           TYPE     STATE        ADDR
lo0/v4            static   ok           127.0.0.1/8
lo0/v6            static   ok           ::1/128
vnic2/v6          addrconf ok           fe80::8:20ff:fe54:569d/10
vnic2/underlay    static   ok           fd00:1122:3344:101::3/64
root@omicron:~# netstat -nr -f inet6
Routing Table: IPv6
  Destination/Mask            Gateway                   Flags Ref   Use    If
--------------------------- --------------------------- ----- --- ------- -----
::1                         ::1                         UH      2       0 lo0
fd00:1122:3344:101::/64     fd00:1122:3344:101::3       U       3       4 vnic2
fd00:1122:3344::/48         fd00:1122:3344:101::1       UG      2       5
fe80::/10                   fe80::8:20ff:fe54:569d      U       2       0 vnic2

Ping the DNS zone

root@omicron:~# ping fd00:1122:3344:0001::1
ICMPv6 redirect from gateway fe80::8:20ff:fefc:a943
 to fd00:1122:3344:1::1 for fd00:1122:3344:1::1
fd00:1122:3344:0001::1 is alive

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As of 44dc885 , I am automatically adding these routes within the Sled Agent, and confirm connectivity between all zones / GZ.

});
let addr = IpNetwork::new(ip, prefix).unwrap();
AddressRequest::Static(addr)
Expand Down Expand Up @@ -543,13 +544,13 @@ impl Zones {
// should remove this function when Sled Agents are provided IPv6 addresses
// from RSS.
pub fn ensure_has_global_zone_v6_address(
link: PhysicalLink,
link: EtherstubVnic,
address: Ipv6Addr,
name: &str,
) -> Result<(), EnsureGzAddressError> {
// Call the guts of this function within a closure to make it easier
// to wrap the error with appropriate context.
|link: PhysicalLink, address, name| -> Result<(), anyhow::Error> {
|link: EtherstubVnic, address, name| -> Result<(), anyhow::Error> {
let gz_link_local_addrobj = AddrObject::new(&link.0, "linklocal")
.map_err(|err| anyhow!(err))?;
Self::ensure_has_link_local_v6_address(
Expand Down
4 changes: 2 additions & 2 deletions sled-agent/src/instance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -671,7 +671,7 @@ impl Instance {
#[cfg(test)]
mod test {
use super::*;
use crate::illumos::dladm::PhysicalLink;
use crate::illumos::dladm::Etherstub;
use crate::mocks::MockNexusClient;
use crate::opte::OptePortAllocator;
use crate::params::InstanceStateRequested;
Expand Down Expand Up @@ -742,7 +742,7 @@ mod test {
let log = logger();
let vnic_allocator = VnicAllocator::new(
"Test".to_string(),
PhysicalLink("mylink".to_string()),
Etherstub("mylink".to_string()),
);
let port_allocator = OptePortAllocator::new();
let nexus_client = MockNexusClient::default();
Expand Down
12 changes: 6 additions & 6 deletions sled-agent/src/instance_manager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

//! API for controlling multiple instances on a sled.

use crate::illumos::dladm::PhysicalLink;
use crate::illumos::dladm::Etherstub;
use crate::illumos::vnic::VnicAllocator;
use crate::nexus::NexusClient;
use crate::opte::OptePortAllocator;
Expand Down Expand Up @@ -54,15 +54,15 @@ impl InstanceManager {
pub fn new(
log: Logger,
nexus_client: Arc<NexusClient>,
physical_link: PhysicalLink,
etherstub: Etherstub,
underlay_addr: Ipv6Addr,
) -> InstanceManager {
InstanceManager {
inner: Arc::new(InstanceManagerInternal {
log: log.new(o!("component" => "InstanceManager")),
nexus_client,
instances: Mutex::new(BTreeMap::new()),
vnic_allocator: VnicAllocator::new("Instance", physical_link),
vnic_allocator: VnicAllocator::new("Instance", etherstub),
underlay_addr,
port_allocator: OptePortAllocator::new(),
}),
Expand Down Expand Up @@ -196,7 +196,7 @@ impl Drop for InstanceTicket {
#[cfg(test)]
mod test {
use super::*;
use crate::illumos::dladm::PhysicalLink;
use crate::illumos::dladm::Etherstub;
use crate::illumos::{dladm::MockDladm, zone::MockZones};
use crate::instance::MockInstance;
use crate::mocks::MockNexusClient;
Expand Down Expand Up @@ -260,7 +260,7 @@ mod test {
let im = InstanceManager::new(
log,
nexus_client,
PhysicalLink("mylink".to_string()),
Etherstub("mylink".to_string()),
std::net::Ipv6Addr::new(
0xfd00, 0x1de, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
),
Expand Down Expand Up @@ -342,7 +342,7 @@ mod test {
let im = InstanceManager::new(
log,
nexus_client,
PhysicalLink("mylink".to_string()),
Etherstub("mylink".to_string()),
std::net::Ipv6Addr::new(
0xfd00, 0x1de, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
),
Expand Down
Loading