Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ipsec: Support type, hostaddrfamily and clientaddrfamily options #2526

Merged
merged 3 commits into from
Jan 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
6 changes: 0 additions & 6 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,6 @@ jobs:
matrix:
include:
- os_type: "el9"
- os_type: "el8"
steps:
- uses: actions/checkout@v3
- name: build nmstate rpm
Expand Down Expand Up @@ -137,11 +136,6 @@ jobs:
- name: Enable openvswitch kernel module
run: sudo modprobe openvswitch

- name: Download compiled EL8 rpm
uses: actions/download-artifact@v3
with:
name: rpms_el8
path: rpms/el8
- name: Download compiled EL9 rpm
uses: actions/download-artifact@v3
with:
Expand Down
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