Skip to content

Commit

Permalink
ipsec: Support type, hostaddrfamily and clientaddrfamily options
Browse files Browse the repository at this point in the history
Added support of:
 * `type: tunnel|transport`
 * `clientaddrfamily: ipv4|ipv6`
 * `hostaddrfamily: ipv4|ipv6`

Integration test cases included.

Signed-off-by: Gris Ge <fge@redhat.com>
  • Loading branch information
cathay4t committed Jan 17, 2024
1 parent 8d90699 commit d7d62db
Show file tree
Hide file tree
Showing 6 changed files with 329 additions and 8 deletions.
54 changes: 54 additions & 0 deletions rust/src/lib/ifaces/ipsec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,12 @@ pub struct LibreswanConfig {
pub rightsubnet: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub leftmodecfgclient: Option<bool>,
#[serde(rename = "type", skip_serializing_if = "Option::is_none")]
pub kind: Option<LibreswanConnectionType>,
#[serde(skip_serializing_if = "Option::is_none")]
pub hostaddrfamily: Option<LibreswanAddressFamily>,
#[serde(skip_serializing_if = "Option::is_none")]
pub clientaddrfamily: Option<LibreswanAddressFamily>,
}

impl LibreswanConfig {
Expand Down Expand Up @@ -162,3 +168,51 @@ where
)),
}
}

#[derive(
Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, Default,
)]
#[non_exhaustive]
#[serde(rename_all = "lowercase")]
pub enum LibreswanConnectionType {
#[default]
Tunnel,
Transport,
}

impl std::fmt::Display for LibreswanConnectionType {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(
f,
"{}",
match self {
Self::Tunnel => "tunnel",
Self::Transport => "transport",
}
)
}
}

#[derive(
Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, Default,
)]
#[non_exhaustive]
#[serde(rename_all = "lowercase")]
pub enum LibreswanAddressFamily {
#[default]
Ipv4,
Ipv6,
}

impl std::fmt::Display for LibreswanAddressFamily {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(
f,
"{}",
match self {
Self::Ipv4 => "ipv4",
Self::Ipv6 => "ipv6",
}
)
}
}
5 changes: 4 additions & 1 deletion rust/src/lib/ifaces/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,10 @@ pub use hsr::{HsrConfig, HsrInterface, HsrProtocol};
pub use infiniband::{InfiniBandConfig, InfiniBandInterface, InfiniBandMode};
pub(crate) use inter_ifaces::MergedInterfaces;
pub use inter_ifaces::*;
pub use ipsec::{IpsecInterface, LibreswanConfig};
pub use ipsec::{
IpsecInterface, LibreswanAddressFamily, LibreswanConfig,
LibreswanConnectionType,
};
pub use linux_bridge::{
LinuxBridgeConfig, LinuxBridgeInterface, LinuxBridgeMulticastRouterType,
LinuxBridgeOptions, LinuxBridgePortConfig, LinuxBridgeStpOptions,
Expand Down
13 changes: 7 additions & 6 deletions rust/src/lib/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -141,12 +141,13 @@ pub use crate::ifaces::{
EthernetDuplex, EthernetInterface, EthtoolCoalesceConfig, EthtoolConfig,
EthtoolFeatureConfig, EthtoolPauseConfig, EthtoolRingConfig, HsrConfig,
HsrInterface, HsrProtocol, InfiniBandConfig, InfiniBandInterface,
InfiniBandMode, Interfaces, IpsecInterface, LibreswanConfig,
LinuxBridgeConfig, LinuxBridgeInterface, LinuxBridgeMulticastRouterType,
LinuxBridgeOptions, LinuxBridgePortConfig, LinuxBridgeStpOptions,
LoopbackInterface, MacSecConfig, MacSecInterface, MacSecValidate,
MacVlanConfig, MacVlanInterface, MacVlanMode, MacVtapConfig,
MacVtapInterface, MacVtapMode, OvsBridgeBondConfig, OvsBridgeBondMode,
InfiniBandMode, Interfaces, IpsecInterface, LibreswanAddressFamily,
LibreswanConfig, LibreswanConnectionType, LinuxBridgeConfig,
LinuxBridgeInterface, LinuxBridgeMulticastRouterType, LinuxBridgeOptions,
LinuxBridgePortConfig, LinuxBridgeStpOptions, LoopbackInterface,
MacSecConfig, MacSecInterface, MacSecValidate, MacVlanConfig,
MacVlanInterface, MacVlanMode, MacVtapConfig, MacVtapInterface,
MacVtapMode, OvsBridgeBondConfig, OvsBridgeBondMode,
OvsBridgeBondPortConfig, OvsBridgeConfig, OvsBridgeInterface,
OvsBridgeOptions, OvsBridgePortConfig, OvsBridgeStpOptions, OvsDpdkConfig,
OvsInterface, OvsPatchConfig, SrIovConfig, SrIovVfConfig, VethConfig,
Expand Down
32 changes: 31 additions & 1 deletion rust/src/lib/nm/query_apply/vpn.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ use std::collections::HashMap;
use std::str::FromStr;

use crate::{
Interface, InterfaceType, IpsecInterface, LibreswanConfig, NmstateError,
Interface, InterfaceType, IpsecInterface, LibreswanAddressFamily,
LibreswanConfig, LibreswanConnectionType, NmstateError,
};

use super::super::{
Expand Down Expand Up @@ -69,6 +70,20 @@ fn get_libreswan_conf(nm_set_vpn: &NmSettingVpn) -> LibreswanConfig {
ret.leftmodecfgclient =
data.get("leftmodecfgclient").map(|s| s == "yes");
ret.rightsubnet = data.get("rightsubnet").cloned();
ret.kind = data.get("type").and_then(|s| match s.as_str() {
"tunnel" => Some(LibreswanConnectionType::Tunnel),
"transport" => Some(LibreswanConnectionType::Transport),
_ => {
log::warn!("Unknown NetworkManager libreswan type {s}");
None
}
});
ret.hostaddrfamily = data
.get("hostaddrfamily")
.and_then(|s| nm_libreswan_addr_family_to_nmstate(s));
ret.clientaddrfamily = data
.get("clientaddrfamily")
.and_then(|s| nm_libreswan_addr_family_to_nmstate(s));
}
if let Some(secrets) = nm_set_vpn.secrets.as_ref() {
ret.psk = secrets.get("pskvalue").cloned();
Expand All @@ -85,3 +100,18 @@ pub(crate) fn get_match_ipsec_nm_conn<'a>(
.filter(|c| c.iface_type() == Some("vpn") && c.id() == Some(iface_name))
.collect()
}

fn nm_libreswan_addr_family_to_nmstate(
family: &str,
) -> Option<LibreswanAddressFamily> {
match family {
"ipv4" => Some(LibreswanAddressFamily::Ipv4),
"ipv6" => Some(LibreswanAddressFamily::Ipv6),
_ => {
log::warn!(
"Unknown address family {family} from libreswan VPN data"
);
None
}
}
}
9 changes: 9 additions & 0 deletions rust/src/lib/nm/settings/vpn.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,15 @@ pub(crate) fn gen_nm_ipsec_vpn_setting(
if let Some(v) = conf.rightsubnet.as_deref() {
vpn_data.insert("rightsubnet".into(), v.to_string());
}
if let Some(v) = conf.kind {
vpn_data.insert("type".into(), v.to_string());
}
if let Some(v) = conf.clientaddrfamily {
vpn_data.insert("clientaddrfamily".into(), v.to_string());
}
if let Some(v) = conf.hostaddrfamily {
vpn_data.insert("hostaddrfamily".into(), v.to_string());
}

let mut nm_vpn_set = NmSettingVpn::default();
nm_vpn_set.data = Some(vpn_data);
Expand Down

0 comments on commit d7d62db

Please sign in to comment.