Skip to content

Commit

Permalink
WIP: adds testing and begin interface creation
Browse files Browse the repository at this point in the history
  • Loading branch information
b-m-f committed Nov 4, 2022
1 parent 3eaa804 commit 205f288
Show file tree
Hide file tree
Showing 6 changed files with 107 additions and 33 deletions.
1 change: 0 additions & 1 deletion src/commands/setup.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@ impl Setup {
}
}
debug!("{:?}", "Setting up...");
// TODO_WG: load wg-config file here
let network_options = network::types::NetworkOptions::load(input_file)?;

let firewall_driver = match firewall::get_supported_firewall_driver() {
Expand Down
3 changes: 3 additions & 0 deletions src/network/NOTES.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@
- properly parse config
- set up interface

## To change
create network interface name from podman

## To test
- interface config without
- address
Expand Down
19 changes: 16 additions & 3 deletions src/network/netlink.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,13 @@ use crate::{
};
use log::trace;
use netlink_packet_route::{
constants::AF_UNSPEC,
nlas::link::{Info, InfoData, InfoKind, Nla},
AddressMessage, LinkMessage, NetlinkHeader, NetlinkMessage, NetlinkPayload, RouteMessage,
RtnlMessage, AF_INET, AF_INET6, IFF_UP, NLM_F_ACK, NLM_F_CREATE, NLM_F_DUMP, NLM_F_EXCL,
NLM_F_REQUEST, RTN_UNICAST, RTPROT_STATIC, RTPROT_UNSPEC, RT_SCOPE_UNIVERSE, RT_TABLE_MAIN,
nlas::nsid,
AddressMessage, LinkMessage, NetlinkHeader, NetlinkMessage, NetlinkPayload, NsidMessage,
RouteMessage, RtnlMessage, AF_INET, AF_INET6, IFF_UP, NLM_F_ACK, NLM_F_CREATE, NLM_F_DUMP,
NLM_F_EXCL, NLM_F_REQUEST, RTN_UNICAST, RTPROT_STATIC, RTPROT_UNSPEC, RT_SCOPE_UNIVERSE,
RT_TABLE_MAIN,
};
use netlink_sys::{protocols::NETLINK_ROUTE, SocketAddr};

Expand Down Expand Up @@ -154,6 +157,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
59 changes: 40 additions & 19 deletions src/network/wireguard.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,9 +70,9 @@ impl driver::NetworkDriver for WireGuard<'_> {
}

fn validate(&mut self) -> NetavarkResult<()> {
if self.info.per_network_opts.interface_name.is_empty() {
return Err(NetavarkError::msg(NO_CONTAINER_INTERFACE_ERROR));
}
// if self.info.per_network_opts.interface_name.is_empty() {
// return Err(NetavarkError::msg(NO_CONTAINER_INTERFACE_ERROR));
// }

// TODO_WG: Document the option
const WIREGUARD_CONFIG_PATH_OPTION: &str = "wireguard_config_path";
Expand Down Expand Up @@ -154,10 +154,9 @@ impl driver::NetworkDriver for WireGuard<'_> {

let (host_sock, netns_sock) = netlink_sockets;

let container_wireguard_interface = setup(
let container_wireguard_interface = create_wireguard_interface(
host_sock,
netns_sock,
&self.info.per_network_opts.interface_name,
data,
self.info.netns_host,
self.info.netns_container,
Expand Down Expand Up @@ -193,30 +192,52 @@ impl driver::NetworkDriver for WireGuard<'_> {
}
}

fn setup(
fn create_wireguard_interface(
host: &mut netlink::Socket,
netns: &mut netlink::Socket,
if_name: &str,
data: &InternalData,
hostns_fd: RawFd,
netns_fd: RawFd,
) -> NetavarkResult<String> {
// TODO_WG: set up interface on host

let mut create_link_opts = CreateLinkOptions::new(if_name.to_string(), InfoKind::Wireguard);
let mut create_link_opts =
CreateLinkOptions::new(data.interface_name.to_string(), InfoKind::Wireguard);
create_link_opts.mtu = data.mtu as u32;

debug!(
"Creating WireGuard interface {}",
data.interface_name.to_string()
);
host.create_link(create_link_opts.clone())
.wrap("create WireGuard interface: {}");
.wrap("create WireGuard interface: {}")?;

let link = host
.get_link(netlink::LinkID::Name(
data.bridge_interface_name.to_string(),
))
.wrap("get bridge interface")?;
.get_link(netlink::LinkID::Name(data.interface_name.to_string()))
.wrap("get WireGuard interface")?;

for addr in &data.addresses {
debug!(
"Adding Address {} to WireGuard interface {}",
addr,
data.interface_name.to_string()
);
host.add_addr(link.header.index, addr)
.wrap("add ip addr to WireGuard interface")?;
}

// TODO_WG: move interface into container namespace
// TODO_WG: set up routes using AllowedIPs and Address
debug!(
"Moving WireGuard interface {} from namespace {} to container namespace {}",
data.interface_name.to_string(),
hostns_fd,
netns_fd
);
host.set_link_ns(link.header.index, netns_fd)
.wrap("moving WireGuard interface to container network namespace")?;

Ok(data.interface_name.clone())

//
// let master_ifname = match data.host_interface_name.as_ref() {
// "" => get_default_route_interface(host)?,
Expand Down Expand Up @@ -260,9 +281,9 @@ fn setup(
// }
// }
//
Err(NetavarkError::msg(
"failed to get the mac address from the container veth interface",
))
// Err(NetavarkError::msg(
// "failed to get the mac address from the container veth interface",
// ))
}

fn get_default_route_interface(host: &mut netlink::Socket) -> NetavarkResult<String> {
Expand Down Expand Up @@ -445,8 +466,8 @@ fn parse_config(path: &String) -> Result<InternalData, NetavarkError> {
}
}

let random_string: String = Alphanumeric.sample_string(&mut thread_rng(), 12);
interface.interface_name = format!("wg-{}", random_string);
// TODO_WG: pass interface name from outside
interface.interface_name = "wg-test".to_string();
interface.peers = peers;

return Ok(interface);
Expand Down
40 changes: 40 additions & 0 deletions test/400-wireguard.bats
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
#!/usr/bin/env bats -*- bats -*-
#
# macvlan driver test
#

load helpers

function setup() {
basic_setup
}

@test "simple WireGuard setup" {
run_netavark --file ${TESTSDIR}/testfiles/wireguard.json setup $(get_container_netns_path)
result="$output"

# mac=$(jq -r '.podman.interfaces.wg-test.mac_address' <<< "$result" )
# check that interface exists
run_in_container_netns ip -j --details link show wg-test
link_info="$output"
assert_json "$link_info" ".[].address" "==" "$mac" "MAC matches container mac"
assert_json "$link_info" '.[].flags[] | select(.=="UP")' "==" "UP" "Container interface is up"
assert_json "$link_info" ".[].linkinfo.info_kind" "==" "macvlan" "Container interface is a macvlan device"

ipaddr="10.88.0.2/16"
run_in_container_netns ip addr show eth0
assert "$output" "=~" "$ipaddr" "IP address matches container address"
assert_json "$result" ".podman.interfaces.eth0.subnets[0].ipnet" "==" "$ipaddr" "Result contains correct IP address"

# check gateway assignment
run_in_container_netns ip r
assert "$output" "=~" "default via 10.88.0.1" "gateway must be there in default route"
assert_json "$result" ".podman.interfaces.eth0.subnets[0].gateway" == "10.88.0.1" "Result contains gateway address"

run_in_container_netns cat /proc/sys/net/ipv6/conf/eth0/autoconf
assert "0" "autoconf is disabled"

run_netavark --file ${TESTSDIR}/testfiles/macvlan.json teardown $(get_container_netns_path)
assert "" "no errors"
}

18 changes: 8 additions & 10 deletions test/testfiles/wireguard.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,21 @@
"container_id": "someID",
"container_name": "wireguard_test_container",
"networks": {
"wg": {}
"wg": {
"options": {
"wireguard_config_path": "../test.conf"
},
"interface_name": "wg-test"
}
},
"network_info": {
"wg": {
"dns_enabled": false,
"driver": "bridge",
"driver": "wireguard",
"id": "53ce4390f2adb1681eb1a90ec8b48c49c015e0a8d336c197637e7f65e365fa9e",
"internal": false,
"ipv6_enabled": false,
"name": "podman",
"network_interface": "podman0",
"subnets": [
{
"gateway": "10.88.0.1",
"subnet": "10.88.0.0/16"
}
]
"name": "wg"
}
}
}

0 comments on commit 205f288

Please sign in to comment.