Add basic NAT structures

This commit is contained in:
2024-01-08 21:03:39 +01:00
parent 80ecb3c5d2
commit 672e866897
9 changed files with 190 additions and 30 deletions

View File

@@ -0,0 +1,2 @@
pub mod nat_definition;
pub mod nat_lib;

View File

@@ -0,0 +1,39 @@
use std::net::{Ipv4Addr, Ipv6Addr};
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
#[serde(tag = "type", rename_all = "lowercase")]
pub enum NatSource<IPv> {
Interface { name: String },
Ip { ip: IPv },
}
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
pub enum NatProtocol {
TCP,
UDP,
Both,
}
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
#[serde(tag = "type", rename_all = "lowercase")]
pub enum NatHostPort {
Single { port: u16 },
Range { start: u16, end: u16 },
}
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
pub struct Nat<IPv> {
pub protocol: NatProtocol,
pub host_addr: NatSource<IPv>,
pub host_port: NatHostPort,
pub guest_addr: IPv,
pub guest_port: u16,
pub comment: Option<String>,
}
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, Default)]
pub struct NetNat {
pub interface: String,
pub ipv4: Option<Vec<Nat<Ipv4Addr>>>,
pub ipv6: Option<Vec<Nat<Ipv6Addr>>>,
}

View File

@@ -0,0 +1,61 @@
use crate::app_config::AppConfig;
use crate::libvirt_rest_structures::net::{NetworkInfo, NetworkName};
use crate::nat::nat_definition::NetNat;
#[derive(thiserror::Error, Debug)]
enum NatLibError {
#[error("Could not save nat definition, because network bridge name was not specified!")]
MissingNetworkBridgeName,
}
/// Save nat definition
pub fn save_nat_def(net: &NetworkInfo) -> anyhow::Result<()> {
let nat = match net.has_nat_def() {
true => NetNat {
interface: net
.bridge_name
.as_ref()
.ok_or(NatLibError::MissingNetworkBridgeName)?
.to_string(),
ipv4: net
.ip_v4
.as_ref()
.map(|i| i.nat.clone())
.unwrap_or_default(),
ipv6: net
.ip_v6
.as_ref()
.map(|i| i.nat.clone())
.unwrap_or_default(),
},
false => NetNat::default(),
};
let json = serde_json::to_string(&nat)?;
std::fs::write(AppConfig::get().net_nat_path(&net.name), json)?;
Ok(())
}
/// Remove nat definition, if existing
pub fn remove_nat_def(name: &NetworkName) -> anyhow::Result<()> {
let nat_file = AppConfig::get().net_nat_path(name);
if nat_file.exists() {
std::fs::remove_file(nat_file)?;
}
Ok(())
}
/// Load nat definition, if available
pub fn load_nat_def(name: &NetworkName) -> anyhow::Result<NetNat> {
let nat_file = AppConfig::get().net_nat_path(name);
if !nat_file.exists() {
return Ok(NetNat::default());
}
let file = std::fs::read_to_string(nat_file)?;
Ok(serde_json::from_str(&file)?)
}