Skip to content

Commit

Permalink
Add basic gateway parsing
Browse files Browse the repository at this point in the history
  • Loading branch information
jcronenberg committed Oct 18, 2023
1 parent fe96673 commit b0850d2
Show file tree
Hide file tree
Showing 2 changed files with 137 additions and 7 deletions.
96 changes: 89 additions & 7 deletions rust/agama-migrate-wicked/src/interface.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use serde_with::{
formats::CommaSeparator, serde_as, skip_serializing_none, DeserializeFromStr, SerializeDisplay,
StringWithSeparator,
};
use std::{collections::HashMap, str::FromStr};
use std::{collections::HashMap, net::IpAddr, str::FromStr};
use strum_macros::{Display, EnumString};

#[derive(Debug, PartialEq, Default, Serialize, Deserialize)]
Expand Down Expand Up @@ -72,18 +72,22 @@ pub struct Ipv6 {
pub accept_redirects: bool,
}

#[derive(Debug, PartialEq, Default, Serialize, Deserialize)]
#[serde(default)]
#[skip_serializing_none]
#[derive(Debug, PartialEq, Serialize, Deserialize)]
pub struct Ipv4Static {
#[serde(rename = "address", skip_serializing_if = "Option::is_none")]
#[serde(rename = "address")]
pub addresses: Option<Vec<Address>>,
#[serde(rename = "route")]
pub routes: Option<Vec<Route>>,
}

#[derive(Debug, PartialEq, Default, Serialize, Deserialize)]
#[serde(default)]
#[skip_serializing_none]
#[derive(Debug, PartialEq, Serialize, Deserialize)]
pub struct Ipv6Static {
#[serde(rename = "address", skip_serializing_if = "Option::is_none")]
#[serde(rename = "address")]
pub addresses: Option<Vec<Address>>,
#[serde(rename = "route")]
pub routes: Option<Vec<Route>>,
}

#[derive(Debug, PartialEq, Default, Serialize, Deserialize)]
Expand Down Expand Up @@ -131,6 +135,20 @@ pub enum FailOverMac {
Follow,
}

#[skip_serializing_none]
#[derive(Debug, PartialEq, Serialize, Deserialize)]
pub struct Route {
pub destination: Option<String>,
#[serde(rename = "nexthop")]
pub nexthops: Option<Vec<Nexthop>>,
pub priority: Option<u32>,
}

#[derive(Debug, PartialEq, Serialize, Deserialize)]
pub struct Nexthop {
pub gateway: String,
}

#[derive(Debug, PartialEq, SerializeDisplay, DeserializeFromStr, EnumString, Display)]
#[strum(serialize_all = "kebab_case")]
pub enum XmitHashPolicy {
Expand Down Expand Up @@ -471,25 +489,57 @@ impl From<&Interface> for IpConfig {
.unwrap();

let mut addresses: Vec<IpInet> = vec![];
let mut gateway4 = None;
let mut gateway6 = None;
if let Some(ipv4_static) = &val.ipv4_static {
if let Some(addresses_in) = &ipv4_static.addresses {
for addr in addresses_in {
addresses.push(IpInet::from_str(addr.local.as_str()).unwrap());
}
}
if let Some(routes) = &ipv4_static.routes {
for route in routes {
if let Some(nexthops) = &route.nexthops {
// TODO fix when implementing better route handling
// the logged warning isn't really true for multiple hops
// as gateways just can't have multiple nexthops AFAICT
if gateway4.is_some() || nexthops.len() > 1 {
log::warn!("Multiple gateways aren't supported yet");
} else {
gateway4 = Some(IpAddr::from_str(&nexthops[0].gateway).unwrap());
}
}
}
}
}
if let Some(ipv6_static) = &val.ipv6_static {
if let Some(addresses_in) = &ipv6_static.addresses {
for addr in addresses_in {
addresses.push(IpInet::from_str(addr.local.as_str()).unwrap());
}
}
if let Some(routes) = &ipv6_static.routes {
for route in routes {
if let Some(nexthops) = &route.nexthops {
// TODO fix when implementing better route handling
// the logged warning isn't really true for multiple hops
// as gateways just can't have multiple nexthops AFAICT
if gateway6.is_some() || nexthops.len() > 1 {
log::warn!("Multiple gateways aren't supported yet");
} else {
gateway6 = Some(IpAddr::from_str(&nexthops[0].gateway).unwrap());
}
}
}
}
}

IpConfig {
addresses,
method4,
method6,
gateway4,
gateway6,
..Default::default()
}
}
Expand All @@ -510,6 +560,12 @@ mod tests {
addresses: Some(vec![Address {
local: "127.0.0.1/8".to_string(),
}]),
routes: Some(vec![Route {
nexthops: Some(vec![Nexthop {
gateway: "127.0.0.1".to_string(),
}]),
..Default::default()
}]),
}),
ipv6: Ipv6 {
enabled: true,
Expand All @@ -519,6 +575,12 @@ mod tests {
addresses: Some(vec![Address {
local: "::1/128".to_string(),
}]),
routes: Some(vec![Route {
nexthops: Some(vec![Nexthop {
gateway: "::1".to_string(),
}]),
..Default::default()
}]),
}),
..Default::default()
};
Expand All @@ -540,6 +602,26 @@ mod tests {
.to_string(),
"128"
);
assert!(static_connection.base().ip_config.gateway4.is_some());
assert_eq!(
static_connection
.base()
.ip_config
.gateway4
.unwrap()
.to_string(),
"127.0.0.1"
);
assert!(static_connection.base().ip_config.gateway6.is_some());
assert_eq!(
static_connection
.base()
.ip_config
.gateway6
.unwrap()
.to_string(),
"::1"
);
}

#[test]
Expand Down
48 changes: 48 additions & 0 deletions rust/agama-migrate-wicked/tests/single_gateway.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
<interface origin="compat:suse:/etc/sysconfig/network/ifcfg-eth0">
<name>eth0</name>
<control>
<mode>boot</mode>
</control>
<firewall/>
<link/>
<ipv4>
<enabled>true</enabled>
<arp-verify>true</arp-verify>
</ipv4>
<ipv4:static>
<address>
<local>192.168.101.5/24</local>
</address>
<address>
<local>192.168.102.5/24</local>
</address>
<route>
<destination>192.168.101.0/24</destination>
</route>
<route>
<destination>192.168.102.0/24</destination>
</route>
<route>
<nexthop>
<gateway>192.168.102.1</gateway>
</nexthop>
<priority>1</priority>
</route>
</ipv4:static>
<ipv6>
<enabled>true</enabled>
<privacy>prefer-public</privacy>
<accept-redirects>false</accept-redirects>
</ipv6>
<ipv6:static>
<address>
<local>2001:db8:1::5/64</local>
</address>
<route>
<nexthop>
<gateway>2001:db8:1::1</gateway>
</nexthop>
<priority>1</priority>
</route>
</ipv6:static>
</interface>

0 comments on commit b0850d2

Please sign in to comment.