use crate::{
BondConfig, BondInterface, BondMode, EthernetInterface, Interface,
InterfaceType, Interfaces, LinuxBridgeConfig, LinuxBridgeInterface,
LinuxBridgePortConfig, MergedInterfaces, OvsBridgeConfig,
OvsBridgeInterface, OvsBridgePortConfig, OvsInterface, RouteEntry,
RouteRuleEntry, RouteRules, Routes, UnknownInterface, VlanConfig,
VlanInterface,
};
pub(crate) fn new_eth_iface(name: &str) -> Interface {
let mut iface = EthernetInterface::new();
iface.base.name = name.to_string();
Interface::Ethernet(Box::new(iface))
}
pub(crate) fn new_unknown_iface(name: &str) -> Interface {
let mut iface = UnknownInterface::new();
iface.base.name = name.to_string();
Interface::Unknown(Box::new(iface))
}
pub(crate) fn new_br_iface(name: &str) -> Interface {
let mut iface = LinuxBridgeInterface::new();
iface.base.name = name.to_string();
Interface::LinuxBridge(Box::new(iface))
}
fn new_bond_iface(name: &str) -> Interface {
let mut iface = BondInterface::new();
iface.base.name = name.to_string();
Interface::Bond(Box::new(iface))
}
pub(crate) fn new_ovs_br_iface(name: &str, port_names: &[&str]) -> Interface {
let mut br0 = OvsBridgeInterface::new();
br0.base.iface_type = InterfaceType::OvsBridge;
br0.base.name = name.to_string();
let mut br_conf = OvsBridgeConfig::new();
let mut br_port_confs = Vec::new();
for port_name in port_names {
let mut br_port_conf = OvsBridgePortConfig::new();
br_port_conf.name = port_name.to_string();
br_port_confs.push(br_port_conf);
}
br_conf.ports = Some(br_port_confs);
br0.bridge = Some(br_conf);
Interface::OvsBridge(Box::new(br0))
}
pub(crate) fn new_ovs_iface(name: &str, ctrl_name: &str) -> Interface {
let mut iface = OvsInterface::new();
iface.base.iface_type = InterfaceType::OvsInterface;
iface.base.name = name.to_string();
iface.base.controller = Some(ctrl_name.to_string());
iface.base.controller_type = Some(InterfaceType::OvsBridge);
Interface::OvsInterface(Box::new(iface))
}
pub(crate) fn new_vlan_iface(name: &str, parent: &str, id: u16) -> Interface {
let mut iface = VlanInterface::new();
iface.base.name = name.to_string();
iface.base.iface_type = InterfaceType::Vlan;
iface.vlan = Some(VlanConfig {
base_iface: Some(parent.to_string()),
id,
..Default::default()
});
Interface::Vlan(Box::new(iface))
}
pub(crate) fn new_nested_4_ifaces() -> [Interface; 6] {
let br0 = new_br_iface("br0");
let mut br1 = new_br_iface("br1");
let mut br2 = new_br_iface("br2");
let mut br3 = new_br_iface("br3");
let mut p1 = new_eth_iface("p1");
let mut p2 = new_eth_iface("p2");
br1.base_iface_mut().controller = Some("br0".to_string());
br1.base_iface_mut().controller_type = Some(InterfaceType::LinuxBridge);
br2.base_iface_mut().controller = Some("br1".to_string());
br2.base_iface_mut().controller_type = Some(InterfaceType::LinuxBridge);
br3.base_iface_mut().controller = Some("br2".to_string());
br3.base_iface_mut().controller_type = Some(InterfaceType::LinuxBridge);
p1.base_iface_mut().controller = Some("br3".to_string());
p1.base_iface_mut().controller_type = Some(InterfaceType::LinuxBridge);
p2.base_iface_mut().controller = Some("br3".to_string());
p2.base_iface_mut().controller_type = Some(InterfaceType::LinuxBridge);
[br0, br1, br2, br3, p1, p2]
}
pub(crate) fn bridge_with_ports(name: &str, ports: &[&str]) -> Interface {
let ports = ports
.iter()
.map(|port| LinuxBridgePortConfig {
name: port.to_string(),
..Default::default()
})
.collect::<Vec<_>>();
let mut br0 = new_br_iface(name);
if let Interface::LinuxBridge(br) = &mut br0 {
br.bridge = Some(LinuxBridgeConfig {
port: Some(ports),
..Default::default()
})
};
br0
}
pub(crate) fn bond_with_ports(name: &str, ports: &[&str]) -> Interface {
let ports = ports.iter().map(|p| p.to_string()).collect::<Vec<String>>();
let mut iface = new_bond_iface(name);
if let Interface::Bond(bond_iface) = &mut iface {
bond_iface.bond = Some(BondConfig {
mode: Some(BondMode::RoundRobin),
port: Some(ports),
..Default::default()
});
}
iface
}
pub(crate) const TEST_NIC: &str = "eth1";
pub(crate) const TEST_IPV4_NET1: &str = "192.0.2.0/24";
pub(crate) const TEST_IPV4_ADDR1: &str = "198.51.100.1";
pub(crate) const TEST_IPV6_NET1: &str = "2001:db8:1::/64";
pub(crate) const TEST_IPV6_ADDR1: &str = "2001:db8:1::1";
pub(crate) const TEST_IPV6_NET2: &str = "2001:db8:2::/64";
pub(crate) const TEST_IPV6_ADDR2: &str = "2001:db8:2::2";
pub(crate) const TEST_ROUTE_METRIC: i64 = 100;
pub(crate) const TEST_TABLE_ID1: u32 = 101;
pub(crate) const TEST_TABLE_ID2: u32 = 102;
pub(crate) const TEST_RULE_IPV6_FROM: &str = "2001:db8:1::2/128";
pub(crate) const TEST_RULE_IPV4_FROM: &str = "192.0.2.1/32";
pub(crate) const TEST_RULE_IPV6_TO: &str = "2001:db8:2::2/128";
pub(crate) const TEST_RULE_IPV4_TO: &str = "198.51.100.1/32";
pub(crate) const TEST_RULE_PRIORITY1: i64 = 201;
pub(crate) const TEST_RULE_PRIORITY2: i64 = 202;
pub(crate) const TEST_RULE_FWMARK1: u32 = 0x72;
pub(crate) const TEST_RULE_FWMASK1: u32 = 0;
pub(crate) const TEST_RULE_FWMARK2: u32 = 0x50;
pub(crate) const TEST_RULE_FWMASK2: u32 = 0x10;
pub(crate) fn gen_test_routes_conf() -> Routes {
let mut ret = Routes::new();
ret.running = Some(gen_test_route_entries());
ret.config = Some(gen_test_route_entries());
ret
}
pub(crate) fn gen_test_route_entries() -> Vec<RouteEntry> {
vec![
gen_route_entry(TEST_IPV6_NET1, TEST_NIC, TEST_IPV6_ADDR1),
gen_route_entry(TEST_IPV4_NET1, TEST_NIC, TEST_IPV4_ADDR1),
]
}
pub(crate) fn gen_route_entry(
dst: &str,
next_hop_iface: &str,
next_hop_addr: &str,
) -> RouteEntry {
let mut ret = RouteEntry::new();
ret.destination = Some(dst.to_string());
ret.next_hop_iface = Some(next_hop_iface.to_string());
ret.next_hop_addr = Some(next_hop_addr.to_string());
ret.metric = Some(TEST_ROUTE_METRIC);
ret
}
pub(crate) fn gen_test_rules_conf() -> RouteRules {
RouteRules {
config: Some(gen_test_rule_entries()),
}
}
pub(crate) fn gen_test_rule_entries() -> Vec<RouteRuleEntry> {
vec![
gen_rule_entry(
TEST_RULE_IPV6_FROM,
TEST_RULE_IPV6_TO,
TEST_RULE_PRIORITY1,
TEST_TABLE_ID1,
TEST_RULE_FWMARK1,
TEST_RULE_FWMASK1,
),
gen_rule_entry(
TEST_RULE_IPV4_FROM,
TEST_RULE_IPV4_TO,
TEST_RULE_PRIORITY2,
TEST_TABLE_ID2,
TEST_RULE_FWMARK2,
TEST_RULE_FWMASK2,
),
]
}
fn gen_rule_entry(
ip_from: &str,
ip_to: &str,
priority: i64,
table_id: u32,
fwmark: u32,
fwmask: u32,
) -> RouteRuleEntry {
RouteRuleEntry {
family: None,
state: None,
ip_from: Some(ip_from.to_string()),
ip_to: Some(ip_to.to_string()),
table_id: Some(table_id),
priority: Some(priority),
fwmark: Some(fwmark),
fwmask: Some(fwmask),
..Default::default()
}
}
pub(crate) fn new_test_nic_with_static_ip() -> Interface {
serde_yaml::from_str(
r"
name: eth1
type: ethernet
state: up
mtu: 1500
ipv4:
address:
- ip: 192.0.2.252
prefix-length: 24
- ip: 192.0.2.251
prefix-length: 24
dhcp: false
enabled: true
ipv6:
address:
- ip: 2001:db8:2::1
prefix-length: 64
- ip: 2001:db8:1::1
prefix-length: 64
autoconf: false
dhcp: false
enabled: true
",
)
.unwrap()
}
fn new_test_nic2_with_static_ip() -> Interface {
serde_yaml::from_str(
r"
name: eth2
type: ethernet
state: up
mtu: 1500
ipv4:
address:
- ip: 192.0.2.253
prefix-length: 24
- ip: 192.0.2.254
prefix-length: 24
dhcp: false
enabled: true
ipv6:
address:
- ip: 2001:db8:3::1
prefix-length: 64
- ip: 2001:db8:4::1
prefix-length: 64
autoconf: false
dhcp: false
enabled: true
",
)
.unwrap()
}
pub(crate) fn gen_merged_ifaces_for_route_test(
) -> (MergedInterfaces, Interfaces) {
let mut ifaces = Interfaces::new();
ifaces.push(new_test_nic_with_static_ip());
ifaces.push(new_test_nic2_with_static_ip());
let mut current = Interfaces::new();
current.push(new_eth_iface("eth1"));
current.push(new_eth_iface("eth2"));
let merged =
MergedInterfaces::new(ifaces, current.clone(), false, false).unwrap();
(merged, current)
}