Skip to content

Commit

Permalink
Adds WireGuard driver
Browse files Browse the repository at this point in the history
Signed-off-by: Maximilian Ehlers <[email protected]>
  • Loading branch information
b-m-f committed Nov 13, 2022
1 parent 84fbb4a commit 0cd4656
Show file tree
Hide file tree
Showing 60 changed files with 1,988 additions and 22 deletions.
36 changes: 36 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,12 @@ zvariant = "3.4.1"
sha2 = "0.10.6"
netlink-packet-route = "0.13"
netlink-packet-core = "0.4.2"
netlink-packet-wireguard = "0.2.1"
netlink-packet-generic = "0.3.1"
fs2 = "0.4.3"
netlink-sys = "0.8.3"
base64 = "0.13.1"


[build-dependencies]
chrono = { version = "0.4.22", default-features = false, features = ["clock"] }
45 changes: 29 additions & 16 deletions src/commands/setup.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,11 @@ impl Setup {

let (mut hostns, mut netns) =
core_utils::open_netlink_sockets(&self.network_namespace_path)?;
let (mut generic_hostns, mut generic_netns) =
core_utils::open_generic_netlink_sockets(&self.network_namespace_path)?;

// setup loopback, it should be safe to assume that 1 is the loopback index
netns.netlink.set_up(LinkID::ID(1))?;
netns.netlink.as_mut().unwrap().set_up(LinkID::ID(1))?;

let mut drivers = Vec::with_capacity(network_options.network_info.len());

Expand Down Expand Up @@ -105,25 +107,36 @@ impl Setup {
// Only now after we validated all drivers we setup each.
// If there is an error we have to tear down all previous drivers.
for (i, driver) in drivers.iter().enumerate() {
let (status, aardvark_entry) =
match driver.setup((&mut hostns.netlink, &mut netns.netlink)) {
Ok((s, a)) => (s, a),
Err(e) => {
// now teardown the already setup drivers
for dri in drivers.iter().take(i) {
match dri.teardown((&mut hostns.netlink, &mut netns.netlink)) {
Ok(_) => {}
Err(e) => {
error!(
let (status, aardvark_entry) = match driver.setup(
(
&mut hostns.netlink.as_mut().unwrap(),
&mut netns.netlink.as_mut().unwrap(),
),
(
&mut generic_hostns.netlink_generic.as_mut().unwrap(),
&mut generic_netns.netlink_generic.as_mut().unwrap(),
),
) {
Ok((s, a)) => (s, a),
Err(e) => {
// now teardown the already setup drivers
for dri in drivers.iter().take(i) {
match dri.teardown((
&mut hostns.netlink.as_mut().unwrap(),
&mut netns.netlink.as_mut().unwrap(),
)) {
Ok(_) => {}
Err(e) => {
error!(
"failed to cleanup previous networks after setup failed: {}",
e
)
}
};
}
return Err(e);
}
};
}
};
return Err(e);
}
};

let _ = response.insert(driver.network_name(), status);
if let Some(a) = aardvark_entry {
Expand Down
5 changes: 4 additions & 1 deletion src/commands/teardown.rs
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,10 @@ impl Teardown {
}
};

match driver.teardown((&mut hostns.netlink, &mut netns.netlink)) {
match driver.teardown((
&mut hostns.netlink.as_mut().unwrap(),
&mut netns.netlink.as_mut().unwrap(),
)) {
Ok(_) => {}
Err(err) => {
error_list.push(err);
Expand Down
20 changes: 20 additions & 0 deletions src/network/NOTES.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
- https://docs.rs/ipnet/2.5.0/ipnet/enum.IpSubnets.html
- can be used to get smallest subset

- properly parse config
- set up interface

## To change
create network interface name from podman

## To test
- interface config without
- address
- private key
- peer configs without
- allowedIPs
- publickey
- config must be readable
- Interface is up
- routes match the allowedIPs settings

3 changes: 2 additions & 1 deletion src/network/bridge.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ use super::{
internal_types::{
IPAMAddresses, PortForwardConfig, SetupNetwork, TearDownNetwork, TeardownPortForward,
},
netlink,
netlink, netlink_generic,
types::StatusBlock,
};

Expand Down Expand Up @@ -93,6 +93,7 @@ impl driver::NetworkDriver for Bridge<'_> {
fn setup(
&self,
netlink_sockets: (&mut netlink::Socket, &mut netlink::Socket),
_netlink_generic_sockets: (&mut netlink_generic::Socket, &mut netlink_generic::Socket),
) -> NetavarkResult<(StatusBlock, Option<AardvarkEntry>)> {
let data = match &self.data {
Some(d) => d,
Expand Down
1 change: 1 addition & 0 deletions src/network/constants.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ pub const IPAM_NONE: &str = "none";

pub const DRIVER_BRIDGE: &str = "bridge";
pub const DRIVER_MACVLAN: &str = "macvlan";
pub const DRIVER_WIREGUARD: &str = "wireguard";

pub const OPTION_ISOLATE: &str = "isolate";
pub const OPTION_MTU: &str = "mtu";
Expand Down
42 changes: 39 additions & 3 deletions src/network/core_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ use std::str::FromStr;
use sysctl::{Sysctl, SysctlError};

use super::netlink;
use super::netlink_generic;

pub struct CoreUtils {
pub networkns: String,
Expand Down Expand Up @@ -273,7 +274,8 @@ pub struct NamespaceOptions {
/// as long as the File object is valid
pub file: File,
pub fd: RawFd,
pub netlink: netlink::Socket,
pub netlink: Option<netlink::Socket>,
pub netlink_generic: Option<netlink_generic::Socket>,
}

pub fn open_netlink_sockets(
Expand All @@ -296,12 +298,46 @@ pub fn open_netlink_sockets(
NamespaceOptions {
file: hostns.0,
fd: hostns.1,
netlink: host_socket,
netlink: Some(host_socket),
netlink_generic: None,
},
NamespaceOptions {
file: netns.0,
fd: netns.1,
netlink: netns_sock,
netlink: Some(netns_sock),
netlink_generic: None,
},
))
}

pub fn open_generic_netlink_sockets(
netns_path: &str,
) -> NetavarkResult<(NamespaceOptions, NamespaceOptions)> {
let netns = open_netlink_socket(netns_path).wrap("open container netns")?;
let hostns = open_netlink_socket("/proc/self/ns/net").wrap("open host netns")?;

let host_socket = netlink_generic::Socket::new().wrap("host netlink socket")?;

exec_netns!(
hostns.1,
netns.1,
res,
netlink_generic::Socket::new().wrap("netns netlink socket")
);

let netns_sock = res?;
Ok((
NamespaceOptions {
file: hostns.0,
fd: hostns.1,
netlink: None,
netlink_generic: Some(host_socket),
},
NamespaceOptions {
file: netns.0,
fd: netns.1,
netlink: None,
netlink_generic: Some(netns_sock),
},
))
}
Expand Down
5 changes: 4 additions & 1 deletion src/network/driver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,9 @@ use super::{
bridge::Bridge,
constants,
macvlan::MacVlan,
netlink,
netlink, netlink_generic,
types::{Network, PerNetworkOptions, PortMapping, StatusBlock},
wireguard::WireGuard,
};
use std::os::unix::io::RawFd;

Expand All @@ -35,6 +36,7 @@ pub trait NetworkDriver {
fn setup(
&self,
netlink_sockets: (&mut netlink::Socket, &mut netlink::Socket),
netlink_generic_sockets: (&mut netlink_generic::Socket, &mut netlink_generic::Socket),
) -> NetavarkResult<(StatusBlock, Option<AardvarkEntry>)>;
/// teardown the network interfaces/firewall rules for this driver
fn teardown(
Expand All @@ -50,6 +52,7 @@ pub fn get_network_driver(info: DriverInfo) -> NetavarkResult<Box<dyn NetworkDri
match info.network.driver.as_str() {
constants::DRIVER_BRIDGE => Ok(Box::new(Bridge::new(info))),
constants::DRIVER_MACVLAN => Ok(Box::new(MacVlan::new(info))),
constants::DRIVER_WIREGUARD => Ok(Box::new(WireGuard::new(info))),

_ => Err(NetavarkError::Message(format!(
"unknown network driver {}",
Expand Down
2 changes: 2 additions & 0 deletions src/network/macvlan.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ use super::{
driver::{self, DriverInfo},
internal_types::IPAMAddresses,
netlink::{self, CreateLinkOptions},
netlink_generic,
types::{NetInterface, StatusBlock},
};

Expand Down Expand Up @@ -94,6 +95,7 @@ impl driver::NetworkDriver for MacVlan<'_> {
fn setup(
&self,
netlink_sockets: (&mut netlink::Socket, &mut netlink::Socket),
_netlink_generic_sockets: (&mut netlink_generic::Socket, &mut netlink_generic::Socket),
) -> Result<(StatusBlock, Option<AardvarkEntry>), NetavarkError> {
let data = match &self.data {
Some(d) => d,
Expand Down
2 changes: 2 additions & 0 deletions src/network/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ pub mod driver;
pub mod internal_types;
pub mod macvlan;
pub mod netlink;
pub mod netlink_generic;
pub mod wireguard;

impl types::NetworkOptions {
pub fn load(path: Option<String>) -> NetavarkResult<types::NetworkOptions> {
Expand Down
10 changes: 10 additions & 0 deletions src/network/netlink.rs
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,16 @@ impl Socket {
Ok(())
}

pub fn set_link_ns(&mut self, link_id: u32, netns_fd: i32) -> NetavarkResult<()> {
let mut msg = LinkMessage::default();
msg.header.index = link_id;
msg.nlas.push(Nla::NetNsFd(netns_fd));

let result = self.make_netlink_request(RtnlMessage::SetLink(msg), NLM_F_ACK)?;
expect_netlink_result!(result, 0);
Ok(())
}

fn create_addr_msg(link_id: u32, addr: &ipnet::IpNet) -> AddressMessage {
let mut msg = AddressMessage::default();
msg.header.index = link_id;
Expand Down
Loading

0 comments on commit 0cd4656

Please sign in to comment.