Skip to content
Open
Show file tree
Hide file tree
Changes from all 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
7 changes: 5 additions & 2 deletions src/commands/setup.rs
Original file line number Diff line number Diff line change
Expand Up @@ -160,8 +160,11 @@ impl Setup {
}
}

fn teardown_drivers<'a, I>(drivers: I, host: &mut netlink::Socket, netns: &mut netlink::Socket)
where
fn teardown_drivers<'a, I>(
drivers: I,
host: &mut netlink::Socket,
netns: &mut netlink::Socket<netlink::ContainerNS>,
) where
I: Iterator<Item = &'a Box<dyn NetworkDriver + 'a>>,
{
for driver in drivers {
Expand Down
8 changes: 4 additions & 4 deletions src/dhcp_proxy/ip.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ trait Address<T> {
fn new(l: &Lease, interface: &str) -> Result<Self, ProxyError>
where
Self: Sized;
fn add_ip(&self, nls: &mut Socket) -> Result<(), ProxyError>;
fn add_gws(&self, nls: &mut Socket) -> Result<(), ProxyError>;
fn add_ip(&self, nls: &mut Socket<netlink::ContainerNS>) -> Result<(), ProxyError>;
fn add_gws(&self, nls: &mut Socket<netlink::ContainerNS>) -> Result<(), ProxyError>;
}

fn handle_gws(g: Vec<String>, netmask: &str) -> Result<Vec<IpNet>, ProxyError> {
Expand Down Expand Up @@ -112,7 +112,7 @@ impl Address<Ipv4Addr> for MacVLAN {
}

// add the ip address to the container namespace
fn add_ip(&self, nls: &mut Socket) -> Result<(), ProxyError> {
fn add_ip(&self, nls: &mut netlink::Socket<netlink::ContainerNS>) -> Result<(), ProxyError> {
debug!("adding network information for {}", self.interface);
let ip = IpNet::new(self.address, self.prefix_length)?;
let dev = nls.get_link(netlink::LinkID::Name(self.interface.clone()))?;
Expand All @@ -123,7 +123,7 @@ impl Address<Ipv4Addr> for MacVLAN {
}

// add one or more routes to the container namespace
fn add_gws(&self, nls: &mut Socket) -> Result<(), ProxyError> {
fn add_gws(&self, nls: &mut Socket<netlink::ContainerNS>) -> Result<(), ProxyError> {
debug!("adding gateways to {}", self.interface);
match core_utils::add_default_routes(nls, &self.gateways, None) {
Ok(_) => Ok(()),
Expand Down
16 changes: 11 additions & 5 deletions src/network/bridge.rs
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,10 @@ impl driver::NetworkDriver for Bridge<'_> {

fn setup(
&self,
netlink_sockets: (&mut netlink::Socket, &mut netlink::Socket),
netlink_sockets: (
&mut netlink::Socket,
&mut netlink::Socket<netlink::ContainerNS>,
),
) -> NetavarkResult<(StatusBlock, Option<AardvarkEntry>)> {
let data = match &self.data {
Some(d) => d,
Expand Down Expand Up @@ -302,7 +305,10 @@ impl driver::NetworkDriver for Bridge<'_> {

fn teardown(
&self,
netlink_sockets: (&mut netlink::Socket, &mut netlink::Socket),
netlink_sockets: (
&mut netlink::Socket,
&mut netlink::Socket<netlink::ContainerNS>,
),
) -> NetavarkResult<()> {
let mode: Option<String> = parse_option(&self.info.network.options, OPTION_MODE)?;
let mode = get_bridge_mode_from_string(mode.as_deref())?;
Expand Down Expand Up @@ -547,7 +553,7 @@ const IPV6_FORWARD: &str = "net/ipv6/conf/all/forwarding";
/// returns the container veth mac address
fn create_interfaces(
host: &mut netlink::Socket,
netns: &mut netlink::Socket,
netns: &mut netlink::Socket<netlink::ContainerNS>,
data: &InternalData,
internal: bool,
rootless: bool,
Expand Down Expand Up @@ -745,7 +751,7 @@ fn create_interfaces(
#[allow(clippy::too_many_arguments)]
fn create_veth_pair<'fd>(
host: &mut netlink::Socket,
netns: &mut netlink::Socket,
netns: &mut netlink::Socket<netlink::ContainerNS>,
data: &InternalData,
primary_index: u32,
bridge_mac: Option<Vec<u8>>,
Expand Down Expand Up @@ -992,7 +998,7 @@ fn check_link_is_vrf(msg: LinkMessage, vrf_name: &str) -> NetavarkResult<LinkMes

fn remove_link(
host: &mut netlink::Socket,
netns: &mut netlink::Socket,
netns: &mut netlink::Socket<netlink::ContainerNS>,
mode: BridgeMode,
br_name: &str,
container_veth_name: &str,
Expand Down
15 changes: 9 additions & 6 deletions src/network/core_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -270,24 +270,27 @@ macro_rules! exec_netns {
}};
}

pub struct NamespaceOptions {
pub struct NamespaceOptions<N: netlink::Namespace> {
/// Note we have to return the File object since the fd is only valid
/// as long as the File object is valid
pub file: File,
pub netlink: netlink::Socket,
pub netlink: netlink::Socket<N>,
}

pub fn open_netlink_sockets(
netns_path: &str,
) -> NetavarkResult<(NamespaceOptions, NamespaceOptions)> {
) -> NetavarkResult<(
NamespaceOptions<netlink::HostNS>,
NamespaceOptions<netlink::ContainerNS>,
)> {
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::Socket::new().wrap("host netlink socket")?;
let host_socket = netlink::Socket::<netlink::HostNS>::new().wrap("host netlink socket")?;
let netns_sock = exec_netns!(
hostns.as_fd(),
netns.as_fd(),
netlink::Socket::new().wrap("netns netlink socket")
netlink::Socket::<netlink::ContainerNS>::new().wrap("netns netlink socket")
)?;

Ok((
Expand All @@ -307,7 +310,7 @@ fn open_netlink_socket(netns_path: &str) -> NetavarkResult<File> {
}

pub fn add_default_routes(
sock: &mut netlink::Socket,
sock: &mut netlink::Socket<netlink::ContainerNS>,
gws: &[ipnet::IpNet],
metric: Option<u32>,
) -> NetavarkResult<()> {
Expand Down
5 changes: 4 additions & 1 deletion src/network/dhcp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,10 @@ pub fn release_dhcp_lease(
Ok(())
}

pub fn dhcp_teardown(info: &DriverInfo, sock: &mut netlink::Socket) -> NetavarkResult<()> {
pub fn dhcp_teardown(
info: &DriverInfo,
sock: &mut netlink::Socket<netlink::ContainerNS>,
) -> NetavarkResult<()> {
let ipam = core_utils::get_ipam_addresses(info.per_network_opts, info.network)?;
let if_name = info.per_network_opts.interface_name.clone();

Expand Down
10 changes: 8 additions & 2 deletions src/network/driver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,18 @@ pub trait NetworkDriver {
/// setup the network interfaces/firewall rules for this driver
fn setup(
&self,
netlink_sockets: (&mut netlink::Socket, &mut netlink::Socket),
netlink_sockets: (
&mut netlink::Socket,
&mut netlink::Socket<netlink::ContainerNS>,
Comment on lines +41 to +43
Copy link

Choose a reason for hiding this comment

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

suggestion: The trait now enforces correct netlink socket types, but the first socket is still untyped.

Consider specifying the first socket as Socket to ensure type safety for both sockets.

),
) -> NetavarkResult<(StatusBlock, Option<AardvarkEntry>)>;
/// teardown the network interfaces/firewall rules for this driver
fn teardown(
&self,
netlink_sockets: (&mut netlink::Socket, &mut netlink::Socket),
netlink_sockets: (
&mut netlink::Socket,
&mut netlink::Socket<netlink::ContainerNS>,
),
) -> NetavarkResult<()>;

/// return the network name
Expand Down
18 changes: 15 additions & 3 deletions src/network/netlink.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,22 @@ use netlink_packet_route::{
};
use netlink_sys::{protocols::NETLINK_ROUTE, SocketAddr};

pub struct Socket {
/// Marker trait for the Socket so we know it refers to either HostNS or ContainerNS.
pub trait Namespace {}
pub struct HostNS;
pub struct ContainerNS;
impl Namespace for HostNS {}
impl Namespace for ContainerNS {}

pub struct Socket<N: Namespace = HostNS> {
socket: netlink_sys::Socket,
sequence_number: u32,
/// buffer size for reading netlink messages, see NLMSG_GOODSIZE in the kernel
buffer: [u8; 8192],

/// Marker for host or container namespace, allows functions to specify which netns
/// socket they need which then gets enforced at compile time without any runtime overhead.
_marker: std::marker::PhantomData<N>,
}

#[derive(Clone)]
Expand Down Expand Up @@ -110,8 +121,8 @@ macro_rules! function {
}};
}

impl Socket {
pub fn new() -> NetavarkResult<Socket> {
impl<N: Namespace> Socket<N> {
pub fn new() -> NetavarkResult<Socket<N>> {
let mut socket = wrap!(netlink_sys::Socket::new(NETLINK_ROUTE), "open")?;
let addr = &SocketAddr::new(0, 0);
wrap!(socket.bind(addr), "bind")?;
Expand All @@ -121,6 +132,7 @@ impl Socket {
socket,
sequence_number: 0,
buffer: [0; 8192],
_marker: std::marker::PhantomData,
})
}

Expand Down
10 changes: 8 additions & 2 deletions src/network/plugin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,10 @@ impl NetworkDriver for PluginDriver<'_> {

fn setup(
&self,
_netlink_sockets: (&mut super::netlink::Socket, &mut super::netlink::Socket),
_netlink_sockets: (
&mut super::netlink::Socket,
&mut super::netlink::Socket<super::netlink::ContainerNS>,
),
) -> NetavarkResult<(types::StatusBlock, Option<AardvarkEntry>)> {
let result = self.exec_plugin(true, self.info.netns_path).wrap(format!(
"plugin {:?} failed",
Expand All @@ -49,7 +52,10 @@ impl NetworkDriver for PluginDriver<'_> {

fn teardown(
&self,
_netlink_sockets: (&mut super::netlink::Socket, &mut super::netlink::Socket),
_netlink_sockets: (
&mut super::netlink::Socket,
&mut super::netlink::Socket<super::netlink::ContainerNS>,
),
) -> NetavarkResult<()> {
self.exec_plugin(false, self.info.netns_path).wrap(format!(
"plugin {:?} failed",
Expand Down
12 changes: 9 additions & 3 deletions src/network/vlan.rs
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,10 @@ impl driver::NetworkDriver for Vlan<'_> {

fn setup(
&self,
netlink_sockets: (&mut netlink::Socket, &mut netlink::Socket),
netlink_sockets: (
&mut netlink::Socket,
&mut netlink::Socket<netlink::ContainerNS>,
),
) -> Result<(StatusBlock, Option<AardvarkEntry>), NetavarkError> {
let data = match &self.data {
Some(d) => d,
Expand Down Expand Up @@ -218,7 +221,10 @@ impl driver::NetworkDriver for Vlan<'_> {

fn teardown(
&self,
netlink_sockets: (&mut netlink::Socket, &mut netlink::Socket),
netlink_sockets: (
&mut netlink::Socket,
&mut netlink::Socket<netlink::ContainerNS>,
),
) -> NetavarkResult<()> {
dhcp_teardown(&self.info, netlink_sockets.1)?;

Expand All @@ -236,7 +242,7 @@ impl driver::NetworkDriver for Vlan<'_> {

fn setup(
host: &mut netlink::Socket,
netns: &mut netlink::Socket,
netns: &mut netlink::Socket<netlink::ContainerNS>,
if_name: &str,
data: &InternalData,
hostns_fd: BorrowedFd<'_>,
Expand Down
15 changes: 9 additions & 6 deletions src/test/netlink.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,16 @@ mod tests {
#[test]
fn test_socket_new() {
test_setup!();
assert!(Socket::new().is_ok(), "Netlink Socket::new() should work");
assert!(
Socket::<HostNS>::new().is_ok(),
"Netlink Socket::<HostNS>::new() should work"
);
}

#[test]
fn test_add_link() {
test_setup!();
let mut sock = Socket::new().expect("Socket::new()");
let mut sock = Socket::<HostNS>::new().expect("Socket::<HostNS>::new()");

let name = String::from("test1");
sock.create_link(CreateLinkOptions::new(name.clone(), InfoKind::Dummy))
Expand All @@ -49,7 +52,7 @@ mod tests {
#[test]
fn test_add_addr() {
test_setup!();
let mut sock = Socket::new().expect("Socket::new()");
let mut sock = Socket::<HostNS>::new().expect("Socket::<HostNS>::new()");

let out = run_command!("ip", "link", "add", "test1", "type", "dummy");
eprintln!("{}", String::from_utf8(out.stderr).unwrap());
Expand All @@ -72,7 +75,7 @@ mod tests {
#[test]
fn test_del_addr() {
test_setup!();
let mut sock = Socket::new().expect("Socket::new()");
let mut sock = Socket::<HostNS>::new().expect("Socket::<HostNS>::new()");

let out = run_command!("ip", "link", "add", "test1", "type", "dummy");
eprintln!("{}", String::from_utf8(out.stderr).unwrap());
Expand Down Expand Up @@ -110,7 +113,7 @@ mod tests {
#[ignore]
fn test_del_route() {
test_setup!();
let mut sock = Socket::new().expect("Socket::new()");
let mut sock = Socket::<HostNS>::new().expect("Socket::<HostNS>::new()");

let out = run_command!("ip", "link", "add", "test1", "type", "dummy");
eprintln!("{}", String::from_utf8(out.stderr).unwrap());
Expand Down Expand Up @@ -159,7 +162,7 @@ mod tests {
#[test]
fn test_dump_addr() {
test_setup!();
let mut sock = Socket::new().expect("Socket::new()");
let mut sock = Socket::<HostNS>::new().expect("Socket::<HostNS>::new()");

let out = run_command!("ip", "link", "add", "test1", "type", "dummy");
eprintln!("{}", String::from_utf8(out.stderr).unwrap());
Expand Down