Skip to content

Commit

Permalink
Merge pull request #840 from Luap99/firewalld-reload
Browse files Browse the repository at this point in the history
Add firewalld reload service
  • Loading branch information
openshift-merge-bot[bot] authored Nov 15, 2023
2 parents 7cd6bc2 + 708bd43 commit 48cc2f4
Show file tree
Hide file tree
Showing 24 changed files with 740 additions and 203 deletions.
27 changes: 14 additions & 13 deletions Cargo.lock

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

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -70,3 +70,4 @@ tonic-build = "0.10"
[dev-dependencies]
once_cell = "1.18.0"
rand = "0.8.5"
tempfile = "3.8.1"
4 changes: 3 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,8 @@ client: bin $(CARGO_TARGET_DIR)
docs: ## build the docs on the host
$(MAKE) -C docs

NV_UNIT_FILES = contrib/systemd/system/netavark-dhcp-proxy.service
NV_UNIT_FILES = contrib/systemd/system/netavark-dhcp-proxy.service \
contrib/systemd/system/netavark-firewalld-reload.service

%.service: %.service.in
sed -e 's;@@NETAVARK@@;$(LIBEXECPODMAN)/netavark;g' $< >$@.tmp.$$ \
Expand All @@ -99,6 +100,7 @@ install: $(NV_UNIT_FILES)
install ${SELINUXOPT} -m 755 -d ${DESTDIR}${SYSTEMDDIR}
install ${SELINUXOPT} -m 644 contrib/systemd/system/netavark-dhcp-proxy.socket ${DESTDIR}${SYSTEMDDIR}/netavark-dhcp-proxy.socket
install ${SELINUXOPT} -m 644 contrib/systemd/system/netavark-dhcp-proxy.service ${DESTDIR}${SYSTEMDDIR}/netavark-dhcp-proxy.service
install ${SELINUXOPT} -m 644 contrib/systemd/system/netavark-firewalld-reload.service ${DESTDIR}${SYSTEMDDIR}/netavark-firewalld-reload.service

.PHONY: uninstall
uninstall:
Expand Down
12 changes: 12 additions & 0 deletions contrib/systemd/system/netavark-firewalld-reload.service.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
[Unit]
Description=Listen for the firewalld reload event and reapply all netavark firewall rules.
# This causes systemd to stop this unit when firewalld is stopped.
PartOf=firewalld.service
After=firewalld.service

[Service]
ExecStart=@@NETAVARK@@ firewalld-reload

[Install]
# If the unit is enabled add a wants to firewalld so it is only started when firewalld is started.
WantedBy=firewalld.service
3 changes: 3 additions & 0 deletions rpm/netavark.spec
Original file line number Diff line number Diff line change
Expand Up @@ -107,9 +107,11 @@ cd docs

%preun
%systemd_preun %{name}-dhcp-proxy.service
%systemd_preun %{name}-firewalld-reload.service

%postun
%systemd_postun %{name}-dhcp-proxy.service
%systemd_postun %{name}-firewalld-reload.service

%files
%license LICENSE
Expand All @@ -118,6 +120,7 @@ cd docs
%{_mandir}/man1/%{name}.1*
%{_unitdir}/%{name}-dhcp-proxy.service
%{_unitdir}/%{name}-dhcp-proxy.socket
%{_unitdir}/%{name}-firewalld-reload.service

%changelog
%if %{defined autochangelog}
Expand Down
66 changes: 66 additions & 0 deletions src/commands/firewalld_reload.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
use zbus::{blocking::Connection, dbus_proxy, CacheProperties};

use crate::{
error::{ErrorWrap, NetavarkResult},
firewall::{get_supported_firewall_driver, state::read_fw_config},
network::constants,
};

#[dbus_proxy(
interface = "org.fedoraproject.FirewallD1",
default_service = "org.fedoraproject.FirewallD1",
default_path = "/org/fedoraproject/FirewallD1"
)]
trait FirewallDDbus {}

const SIGNAL_NAME: &str = "Reloaded";

pub fn listen(config_dir: Option<String>) -> NetavarkResult<()> {
let config_dir = config_dir
.as_deref()
.unwrap_or(constants::DEFAULT_CONFIG_DIR);
log::debug!("looking for firewall configs in {}", config_dir);

let conn = Connection::system()?;
let proxy = FirewallDDbusProxyBlocking::builder(&conn)
.cache_properties(CacheProperties::No)
.build()?;

// Setup fw rules on start because we are started after firewalld
// this means at the time firewalld stated the fw rules were flushed
// and we need to add them back.
// It is important to keep things like "systemctl restart firewalld" working.
reload_rules(config_dir);

// This loops forever until the process is killed or there is some dbus error.
for _ in proxy.receive_signal(SIGNAL_NAME)? {
log::debug!("got firewalld {} signal", SIGNAL_NAME);
reload_rules(config_dir);
}

Ok(())
}

fn reload_rules(config_dir: &str) {
if let Err(e) = reload_rules_inner(config_dir) {
log::error!("failed to reload firewall rules: {e}");
}
}

fn reload_rules_inner(config_dir: &str) -> NetavarkResult<()> {
let conf = read_fw_config(config_dir).wrap("read firewall config")?;
// If we got no conf there are no containers so nothing to do.
if let Some(conf) = conf {
let fw_driver = get_supported_firewall_driver(Some(conf.driver))?;

for net in conf.net_confs {
fw_driver.setup_network(net)?;
}
for port in &conf.port_confs {
fw_driver.setup_port_forward(port.into())?;
}
log::info!("Successfully reloaded firewall rules");
}

Ok(())
}
12 changes: 12 additions & 0 deletions src/commands/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,17 @@
use crate::error::{NetavarkError, NetavarkResult};

pub mod dhcp_proxy;
pub mod firewalld_reload;
pub mod setup;
pub mod teardown;
pub mod update;
pub mod version;

fn get_config_dir(dir: Option<String>, cmd: &str) -> NetavarkResult<String> {
dir.ok_or_else(|| {
NetavarkError::msg(format!(
"--config not specified but required for netavark {}",
cmd
))
})
}
15 changes: 6 additions & 9 deletions src/commands/setup.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
//! Configures the given network namespace with provided specs
use crate::commands::get_config_dir;
use crate::dns::aardvark::Aardvark;
use crate::error::{NetavarkError, NetavarkResult};
use crate::firewall;
Expand Down Expand Up @@ -47,7 +48,7 @@ impl Setup {
debug!("{:?}", "Setting up...");
let network_options = network::types::NetworkOptions::load(input_file)?;

let firewall_driver = match firewall::get_supported_firewall_driver() {
let firewall_driver = match firewall::get_supported_firewall_driver(None) {
Ok(driver) => driver,
Err(e) => return Err(e),
};
Expand All @@ -62,6 +63,7 @@ impl Setup {
// setup loopback, it should be safe to assume that 1 is the loopback index
netns.netlink.set_up(LinkID::ID(1))?;

let config_dir = get_config_dir(config_dir, "setup")?;
let mut drivers = Vec::with_capacity(network_options.network_info.len());

// Perform per-network setup
Expand All @@ -83,6 +85,8 @@ impl Setup {
per_network_opts,
port_mappings: &network_options.port_mappings,
dns_port,
config_dir: &config_dir,
rootless,
},
&plugin_directories,
)?;
Expand Down Expand Up @@ -126,14 +130,7 @@ impl Setup {

if !aardvark_entries.is_empty() {
if Path::new(&aardvark_bin).exists() {
let path = match config_dir {
Some(dir) => Path::new(&dir).join("aardvark-dns"),
None => {
return Err(NetavarkError::msg(
"dns is requested but --config not specified",
))
}
};
let path = Path::new(&config_dir).join("aardvark-dns");

match fs::create_dir(path.as_path()) {
Ok(_) => {}
Expand Down
15 changes: 6 additions & 9 deletions src/commands/teardown.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use crate::commands::get_config_dir;
use crate::dns::aardvark::{Aardvark, AardvarkEntry};
use crate::error::{NetavarkError, NetavarkErrorList, NetavarkResult};
use crate::network::constants::DRIVER_BRIDGE;
Expand Down Expand Up @@ -40,6 +41,7 @@ impl Teardown {
let mut error_list = NetavarkErrorList::new();

let dns_port = core_utils::get_netavark_dns_port()?;
let config_dir = get_config_dir(config_dir, "teardown")?;

let mut aardvark_entries = Vec::new();
for (key, network) in &network_options.network_info {
Expand All @@ -59,14 +61,7 @@ impl Teardown {

if !aardvark_entries.is_empty() {
// stop dns server first before netavark clears the interface
let path = match config_dir {
Some(dir) => Path::new(&dir).join("aardvark-dns"),
None => {
return Err(NetavarkError::msg(
"dns is requested but --config not specified",
))
}
};
let path = Path::new(&config_dir).join("aardvark-dns");
if let Ok(path_string) = path.into_os_string().into_string() {
let aardvark_interface =
Aardvark::new(path_string, rootless, aardvark_bin, dns_port);
Expand All @@ -81,7 +76,7 @@ impl Teardown {
}
}

let firewall_driver = match firewall::get_supported_firewall_driver() {
let firewall_driver = match firewall::get_supported_firewall_driver(None) {
Ok(driver) => driver,
Err(e) => return Err(e),
};
Expand Down Expand Up @@ -113,6 +108,8 @@ impl Teardown {
per_network_opts,
port_mappings: &network_options.port_mappings,
dns_port,
config_dir: &config_dir,
rootless,
},
&plugin_directories,
) {
Expand Down
12 changes: 3 additions & 9 deletions src/commands/update.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use crate::commands::get_config_dir;
use crate::dns::aardvark::Aardvark;
use crate::error::{NetavarkError, NetavarkResult};
use crate::network::core_utils;
Expand Down Expand Up @@ -33,16 +34,9 @@ impl Update {
rootless: bool,
) -> NetavarkResult<()> {
let dns_port = core_utils::get_netavark_dns_port()?;

let config_dir = get_config_dir(config_dir, "update")?;
if Path::new(&aardvark_bin).exists() {
let path = match config_dir {
Some(dir) => Path::new(&dir).join("aardvark-dns"),
None => {
return Err(NetavarkError::msg(
"dns is requested but --config not specified",
))
}
};
let path = Path::new(&config_dir).join("aardvark-dns");
if let Ok(path_string) = path.into_os_string().into_string() {
let aardvark_interface =
Aardvark::new(path_string, rootless, aardvark_bin, dns_port);
Expand Down
Loading

0 comments on commit 48cc2f4

Please sign in to comment.