forked from oxidecomputer/omicron
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Zone network configuration service (oxidecomputer#4677)
As part of the work for [self assembling zones](oxidecomputer#1898), it was [suggested](oxidecomputer#4534 (comment)) to break the network configuration out into a separate service. ## Implementation This PR introduces a new SMF service `oxide/zone-network-setup`, which sets up the common initial zone networking configuration for each self assembled zone. Each of the "self assembled zone" services will now depend on this new service to run, and all properties relating to zone network configuration have been removed from these services. The executable which does the actual zone networking setup, is built as a tiny CLI. It takes advantage of clap's parsing validation to make sure we have all of the properties present, and in the format they are intended to be. ## Caveats There are two remaining self assembled zones that don't depend on this new service yet (crucible and crucible-pantry). As these two zones need coordinated PRs with the crucible repo, I'd like to implement these in a follow up PR once this one is approved and merged.
- Loading branch information
Showing
18 changed files
with
424 additions
and
88 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,110 @@ | ||
// This Source Code Form is subject to the terms of the Mozilla Public | ||
// License, v. 2.0. If a copy of the MPL was not distributed with this | ||
// file, You can obtain one at https://mozilla.org/MPL/2.0/. | ||
|
||
//! Utilities for managing IP interfaces. | ||
use crate::zone::IPADM; | ||
use crate::{execute, ExecutionError, PFEXEC}; | ||
use std::net::Ipv6Addr; | ||
|
||
/// Wraps commands for interacting with interfaces. | ||
pub struct Ipadm {} | ||
|
||
#[cfg_attr(any(test, feature = "testing"), mockall::automock)] | ||
impl Ipadm { | ||
// Remove current IP interface and create a new temporary one. | ||
pub fn set_temp_interface_for_datalink( | ||
datalink: &str, | ||
) -> Result<(), ExecutionError> { | ||
let mut cmd = std::process::Command::new(PFEXEC); | ||
let cmd = cmd.args(&[IPADM, "delete-if", datalink]); | ||
// First we remove IP interface if it already exists. If it doesn't | ||
// exist and the command returns an error we continue anyway as | ||
// the next step is to create it. | ||
let _ = execute(cmd); | ||
|
||
let mut cmd = std::process::Command::new(PFEXEC); | ||
let cmd = cmd.args(&[IPADM, "create-if", "-t", datalink]); | ||
execute(cmd)?; | ||
Ok(()) | ||
} | ||
|
||
// Set MTU to 9000 on both IPv4 and IPv6 | ||
pub fn set_interface_mtu(datalink: &str) -> Result<(), ExecutionError> { | ||
let mut cmd = std::process::Command::new(PFEXEC); | ||
let cmd = cmd.args(&[ | ||
IPADM, | ||
"set-ifprop", | ||
"-t", | ||
"-p", | ||
"mtu=9000", | ||
"-m", | ||
"ipv4", | ||
datalink, | ||
]); | ||
execute(cmd)?; | ||
|
||
let mut cmd = std::process::Command::new(PFEXEC); | ||
let cmd = cmd.args(&[ | ||
IPADM, | ||
"set-ifprop", | ||
"-t", | ||
"-p", | ||
"mtu=9000", | ||
"-m", | ||
"ipv6", | ||
datalink, | ||
]); | ||
execute(cmd)?; | ||
Ok(()) | ||
} | ||
|
||
pub fn create_static_and_autoconfigured_addrs( | ||
datalink: &str, | ||
listen_addr: &Ipv6Addr, | ||
) -> Result<(), ExecutionError> { | ||
// Create auto-configured address on the IP interface if it doesn't already exist | ||
let addrobj = format!("{}/ll", datalink); | ||
let mut cmd = std::process::Command::new(PFEXEC); | ||
let cmd = cmd.args(&[IPADM, "show-addr", &addrobj]); | ||
match execute(cmd) { | ||
Err(_) => { | ||
let mut cmd = std::process::Command::new(PFEXEC); | ||
let cmd = cmd.args(&[ | ||
IPADM, | ||
"create-addr", | ||
"-t", | ||
"-T", | ||
"addrconf", | ||
&addrobj, | ||
]); | ||
execute(cmd)?; | ||
} | ||
Ok(_) => (), | ||
}; | ||
|
||
// Create static address on the IP interface if it doesn't already exist | ||
let addrobj = format!("{}/omicron6", datalink); | ||
let mut cmd = std::process::Command::new(PFEXEC); | ||
let cmd = cmd.args(&[IPADM, "show-addr", &addrobj]); | ||
match execute(cmd) { | ||
Err(_) => { | ||
let mut cmd = std::process::Command::new(PFEXEC); | ||
let cmd = cmd.args(&[ | ||
IPADM, | ||
"create-addr", | ||
"-t", | ||
"-T", | ||
"static", | ||
"-a", | ||
&listen_addr.to_string(), | ||
&addrobj, | ||
]); | ||
execute(cmd)?; | ||
} | ||
Ok(_) => (), | ||
}; | ||
Ok(()) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
// This Source Code Form is subject to the terms of the Mozilla Public | ||
// License, v. 2.0. If a copy of the MPL was not distributed with this | ||
// file, You can obtain one at https://mozilla.org/MPL/2.0/. | ||
|
||
//! Utilities for manipulating the routing tables. | ||
use crate::zone::ROUTE; | ||
use crate::{execute, inner, output_to_exec_error, ExecutionError, PFEXEC}; | ||
use libc::ESRCH; | ||
use std::net::Ipv6Addr; | ||
|
||
/// Wraps commands for interacting with routing tables. | ||
pub struct Route {} | ||
|
||
#[cfg_attr(any(test, feature = "testing"), mockall::automock)] | ||
impl Route { | ||
pub fn ensure_default_route_with_gateway( | ||
gateway: &Ipv6Addr, | ||
) -> Result<(), ExecutionError> { | ||
// Add the desired route if it doesn't already exist | ||
let destination = "default"; | ||
let mut cmd = std::process::Command::new(PFEXEC); | ||
let cmd = cmd.args(&[ | ||
ROUTE, | ||
"-n", | ||
"get", | ||
"-inet6", | ||
destination, | ||
"-inet6", | ||
&gateway.to_string(), | ||
]); | ||
|
||
let out = | ||
cmd.output().map_err(|err| ExecutionError::ExecutionStart { | ||
command: inner::to_string(cmd), | ||
err, | ||
})?; | ||
match out.status.code() { | ||
Some(0) => (), | ||
// If the entry is not found in the table, | ||
// the exit status of the command will be 3 (ESRCH). | ||
// When that is the case, we'll add the route. | ||
Some(ESRCH) => { | ||
let mut cmd = std::process::Command::new(PFEXEC); | ||
let cmd = cmd.args(&[ | ||
ROUTE, | ||
"add", | ||
"-inet6", | ||
destination, | ||
"-inet6", | ||
&gateway.to_string(), | ||
]); | ||
execute(cmd)?; | ||
} | ||
Some(_) | None => return Err(output_to_exec_error(cmd, &out)), | ||
}; | ||
Ok(()) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.