use crate::error::{NetavarkError, NetavarkResult};
use crate::network::internal_types::{
PortForwardConfig, SetupNetwork, TearDownNetwork, TeardownPortForward,
};
use log::{debug, info};
use std::env;
use zbus::blocking::Connection;
pub mod firewalld;
pub mod fwnone;
pub mod iptables;
pub mod state;
mod varktables;
const IPTABLES: &str = "iptables";
const FIREWALLD: &str = "firewalld";
const NFTABLES: &str = "nftables";
const NONE: &str = "none";
pub trait FirewallDriver {
fn setup_network(&self, network_setup: SetupNetwork) -> NetavarkResult<()>;
fn teardown_network(&self, tear: TearDownNetwork) -> NetavarkResult<()>;
fn setup_port_forward(&self, setup_pw: PortForwardConfig) -> NetavarkResult<()>;
fn teardown_port_forward(&self, teardown_pf: TeardownPortForward) -> NetavarkResult<()>;
fn driver_name(&self) -> &str;
}
enum FirewallImpl {
Iptables,
Firewalld(Connection),
Nftables,
Fwnone,
}
fn get_firewall_impl(driver_name: Option<String>) -> NetavarkResult<FirewallImpl> {
let driver = driver_name.or_else(|| env::var("NETAVARK_FW").ok());
if let Some(var) = driver {
debug!("Forcibly using firewall driver {}", var);
match var.to_lowercase().as_str() {
FIREWALLD => {
let conn = match Connection::system() {
Ok(c) => c,
Err(e) => {
return Err(NetavarkError::wrap(
"Error retrieving dbus connection for requested firewall backend",
e.into(),
))
}
};
return Ok(FirewallImpl::Firewalld(conn));
}
IPTABLES => return Ok(FirewallImpl::Iptables),
NFTABLES => return Ok(FirewallImpl::Nftables),
NONE => return Ok(FirewallImpl::Fwnone),
any => {
return Err(NetavarkError::Message(format!(
"Must provide a valid firewall backend, got {any}"
)))
}
}
}
Ok(FirewallImpl::Iptables)
}
pub fn get_supported_firewall_driver(
driver_name: Option<String>,
) -> NetavarkResult<Box<dyn FirewallDriver>> {
match get_firewall_impl(driver_name) {
Ok(fw) => match fw {
FirewallImpl::Iptables => {
info!("Using iptables firewall driver");
iptables::new()
}
FirewallImpl::Firewalld(conn) => {
info!("Using firewalld firewall driver");
firewalld::new(conn)
}
FirewallImpl::Nftables => {
info!("Using nftables firewall driver");
Err(NetavarkError::msg(
"nftables support presently not available",
))
}
FirewallImpl::Fwnone => {
info!("Not using firewall");
fwnone::new()
}
},
Err(e) => Err(e),
}
}