use crate::{
nm::route_rule::store_route_rule_config,
unit_tests::testlib::{
gen_test_routes_conf, gen_test_rules_conf, new_eth_iface,
new_test_nic_with_static_ip, TEST_NIC, TEST_RULE_IPV4_FROM,
TEST_RULE_IPV4_TO, TEST_RULE_IPV6_FROM, TEST_RULE_IPV6_TO,
TEST_RULE_PRIORITY1, TEST_RULE_PRIORITY2, TEST_TABLE_ID1,
TEST_TABLE_ID2,
},
InterfaceType, Interfaces, MergedNetworkState, NetworkState,
RouteRuleEntry,
};
#[test]
fn test_add_rules_to_new_interface() {
let mut cur_net_state = NetworkState::new();
cur_net_state.interfaces.push(new_eth_iface(TEST_NIC));
let des_iface = new_test_nic_with_static_ip();
let mut des_ifaces = Interfaces::new();
des_ifaces.push(des_iface);
let mut des_net_state = NetworkState::new();
des_net_state.interfaces = des_ifaces;
des_net_state.routes = gen_test_routes_conf();
des_net_state.rules = gen_test_rules_conf();
let mut merged_state =
MergedNetworkState::new(des_net_state, cur_net_state, false, false)
.unwrap();
store_route_rule_config(&mut merged_state).unwrap();
let iface = merged_state
.interfaces
.get_iface(TEST_NIC, InterfaceType::Unknown)
.unwrap()
.for_apply
.as_ref()
.unwrap();
let ipv6_config_rules = iface
.base_iface()
.ipv6
.as_ref()
.unwrap()
.rules
.as_ref()
.unwrap();
assert_eq!(ipv6_config_rules.len(), 1);
assert_eq!(
ipv6_config_rules[0].ip_from.as_ref().unwrap().as_str(),
TEST_RULE_IPV6_FROM,
);
assert_eq!(
ipv6_config_rules[0].ip_to.as_ref().unwrap().as_str(),
TEST_RULE_IPV6_TO,
);
assert_eq!(ipv6_config_rules[0].priority.unwrap(), TEST_RULE_PRIORITY1);
assert_eq!(ipv6_config_rules[0].table_id.unwrap(), TEST_TABLE_ID1);
let ipv4_config_rules = iface
.base_iface()
.ipv4
.as_ref()
.unwrap()
.rules
.as_ref()
.unwrap();
assert_eq!(ipv4_config_rules.len(), 1);
assert_eq!(
ipv4_config_rules[0].ip_from.as_ref().unwrap().as_str(),
TEST_RULE_IPV4_FROM,
);
assert_eq!(
ipv4_config_rules[0].ip_to.as_ref().unwrap().as_str(),
TEST_RULE_IPV4_TO,
);
assert_eq!(ipv4_config_rules[0].priority.unwrap(), TEST_RULE_PRIORITY2);
assert_eq!(ipv4_config_rules[0].table_id.unwrap(), TEST_TABLE_ID2);
}
#[test]
fn test_route_rule_ignore_absent_ifaces() {
let desired: NetworkState = serde_yaml::from_str(
r"
interfaces:
- name: br0
state: absent
type: linux-bridge
route-rules:
config:
- route-table: 200
state: absent
",
)
.unwrap();
let current: NetworkState = serde_yaml::from_str(
r"
interfaces:
- name: eth1
type: ethernet
state: up
- name: br0
type: linux-bridge
state: up
ipv4:
address:
- ip: 192.0.2.251
prefix-length: 24
dhcp: false
enabled: true
bridge:
options:
stp:
enabled: false
port:
- name: eth1
routes:
config:
- destination: 198.51.100.0/24
metric: 150
next-hop-address: 192.0.2.1
next-hop-interface: br0
table-id: 200
route-rules:
config:
- ip-from: 192.51.100.2/32
route-table: 200
",
)
.unwrap();
let mut merged_state =
MergedNetworkState::new(desired, current, false, false).unwrap();
store_route_rule_config(&mut merged_state).unwrap();
let eth1_iface = merged_state
.interfaces
.get_iface("eth1", InterfaceType::Ethernet)
.unwrap()
.for_apply
.as_ref()
.unwrap();
let br0_iface = merged_state
.interfaces
.get_iface("br0", InterfaceType::LinuxBridge)
.unwrap()
.for_apply
.as_ref()
.unwrap();
assert!(eth1_iface.is_up());
assert!(br0_iface.is_absent());
}
#[test]
fn test_route_rule_use_auto_route_table_id() {
let current: NetworkState = serde_yaml::from_str(
r"
---
interfaces:
- name: br0
type: ovs-interface
state: up
ipv4:
enabled: true
dhcp: true
auto-dns: false
auto-routes: true
auto-gateway: true
auto-route-table-id: 500
ipv6:
enabled: false
- name: br0
type: ovs-bridge
state: up
bridge:
port:
- name: br0
",
)
.unwrap();
let desired: NetworkState = serde_yaml::from_str(
r"
---
route-rules:
config:
- route-table: 500
priority: 3200
ip-to: 192.0.3.0/24
- route-table: 500
priority: 3200
ip-from: 192.0.3.0/24
interfaces:
- name: br0
type: ovs-interface
",
)
.unwrap();
let expected_rules: Vec<RouteRuleEntry> = serde_yaml::from_str(
r"
- route-table: 500
priority: 3200
ip-to: 192.0.3.0/24
- route-table: 500
priority: 3200
ip-from: 192.0.3.0/24
",
)
.unwrap();
let mut merged_state =
MergedNetworkState::new(desired, current, false, false).unwrap();
store_route_rule_config(&mut merged_state).unwrap();
let ovs_iface = merged_state
.interfaces
.get_iface("br0", InterfaceType::OvsInterface)
.unwrap()
.for_apply
.as_ref()
.unwrap();
assert_eq!(ovs_iface.iface_type(), InterfaceType::OvsInterface);
assert_eq!(
ovs_iface.base_iface().ipv4.as_ref().unwrap().rules,
Some(expected_rules)
);
}
#[test]
fn test_route_rule_use_default_auto_route_table_id() {
let current: NetworkState = serde_yaml::from_str(
r"
---
interfaces:
- name: eth1
type: ethernet
state: up
ipv4:
enabled: true
dhcp: true
auto-dns: true
auto-routes: true
auto-gateway: true
ipv6:
enabled: false
",
)
.unwrap();
let desired: NetworkState = serde_yaml::from_str(
r"---
route-rules:
config:
- priority: 3200
ip-to: 192.0.3.0/24
- priority: 3200
ip-from: 192.0.3.0/24
interfaces:
- name: eth1",
)
.unwrap();
let expected_rules: Vec<RouteRuleEntry> = serde_yaml::from_str(
r"
- route-table: 254
priority: 3200
ip-to: 192.0.3.0/24
- route-table: 254
priority: 3200
ip-from: 192.0.3.0/24
",
)
.unwrap();
let mut merged_state =
MergedNetworkState::new(desired, current, false, false).unwrap();
store_route_rule_config(&mut merged_state).unwrap();
let iface = merged_state
.interfaces
.get_iface("eth1", InterfaceType::Ethernet)
.unwrap()
.for_apply
.as_ref()
.unwrap();
assert_eq!(
iface.base_iface().ipv4.as_ref().unwrap().rules,
Some(expected_rules)
);
}
#[test]
fn test_route_rule_use_loopback() {
let current: NetworkState = serde_yaml::from_str(
r"---
interfaces:
- name: lo
type: loopback
state: up
mtu: 65536
ipv4:
enabled: true
address:
- ip: 127.0.0.1
prefix-length: 8
ipv6:
enabled: true
address:
- ip: ::1
prefix-length: 128",
)
.unwrap();
let desired: NetworkState = serde_yaml::from_str(
r"---
route-rules:
config:
- priority: 3200
route-table: 255
family: ipv4
- priority: 3200
route-table: 255
family: ipv6",
)
.unwrap();
let expected_ipv4_rules: Vec<RouteRuleEntry> = serde_yaml::from_str(
r"
- priority: 3200
route-table: 255
family: ipv4",
)
.unwrap();
let expected_ipv6_rules: Vec<RouteRuleEntry> = serde_yaml::from_str(
r"
- priority: 3200
route-table: 255
family: ipv6",
)
.unwrap();
let mut merged_state =
MergedNetworkState::new(desired, current, false, false).unwrap();
store_route_rule_config(&mut merged_state).unwrap();
let iface = merged_state
.interfaces
.get_iface("lo", InterfaceType::Loopback)
.unwrap()
.for_apply
.as_ref()
.unwrap();
assert_eq!(
iface.base_iface().ipv4.as_ref().unwrap().rules,
Some(expected_ipv4_rules)
);
assert_eq!(
iface.base_iface().ipv6.as_ref().unwrap().rules,
Some(expected_ipv6_rules)
);
}