1
0
mirror of https://github.com/containers/youki synced 2025-04-30 13:20:17 +02:00

test: add checks for classid and net_prio to network.rs

Signed-off-by: moz-sec <m0253c@gmail.com>
This commit is contained in:
moz-sec 2025-01-20 13:11:17 +09:00
parent c327345c1b
commit c6e3c0a1db
No known key found for this signature in database
GPG Key ID: E5672AD87468B006

@ -1,6 +1,7 @@
use std::path::Path;
use std::fs;
use std::path::{Path, PathBuf};
use anyhow::{anyhow, Context, Result};
use anyhow::{anyhow, bail, Context, Result};
use oci_spec::runtime::{
LinuxBuilder, LinuxInterfacePriorityBuilder, LinuxNamespace, LinuxNamespaceType,
LinuxNetworkBuilder, LinuxResourcesBuilder, Spec, SpecBuilder,
@ -9,7 +10,7 @@ use pnet_datalink::interfaces;
use test_framework::{test_result, ConditionalTest, TestGroup, TestResult};
use crate::utils::test_outside_container;
use crate::utils::test_utils::check_container_created;
use crate::utils::test_utils::{check_container_created, CGROUP_ROOT};
fn create_spec(
cgroup_name: &str,
@ -115,8 +116,9 @@ fn test_network_cgroups() -> TestResult {
];
for spec in cases.into_iter() {
let test_result = test_outside_container(spec, &|data| {
let test_result = test_outside_container(spec.clone(), &|data| {
test_result!(check_container_created(&data));
test_result!(validate_network(cgroup_name, &spec));
TestResult::Passed
});
@ -128,6 +130,97 @@ fn test_network_cgroups() -> TestResult {
TestResult::Passed
}
/// validates the Network structure parsed from /sys/fs/cgroup/net_cls,net_prio with the spec
fn validate_network(cgroup_name: &str, spec: &Spec) -> Result<()> {
let (net_cls_path, net_prio_path) = if Path::new("/sys/fs/cgroup/net_cls/net_cls.classid")
.exists()
&& Path::new("/sys/fs/cgroup/net_prio/net_prio.ifpriomap").exists()
{
(
net_cls_path(PathBuf::from(CGROUP_ROOT).join("net_cls"), cgroup_name),
net_prio_path(PathBuf::from(CGROUP_ROOT).join("net_prio"), cgroup_name),
)
} else if Path::new("/sys/fs/cgroup/net_cls,net_prio/net_cls.classid").exists()
&& Path::new("/sys/fs/cgroup/net_cls,net_prio/net_prio.ifpriomap").exists()
{
(
net_cls_path(
PathBuf::from(CGROUP_ROOT).join("net_cls,net_prio"),
cgroup_name,
),
net_prio_path(
PathBuf::from(CGROUP_ROOT).join("net_cls,net_prio"),
cgroup_name,
),
)
} else if Path::new("/sys/fs/cgroup/net_prio,net_cls/net_cls.classid").exists()
&& Path::new("/sys/fs/cgroup/net_prio,net_cls/net_prio.ifpriomap").exists()
{
(
net_cls_path(
PathBuf::from(CGROUP_ROOT).join("net_prio,net_cls"),
cgroup_name,
),
net_prio_path(
PathBuf::from(CGROUP_ROOT).join("net_prio,net_cls"),
cgroup_name,
),
)
} else {
return Err(anyhow::anyhow!("Required cgroup paths do not exist"));
};
let resources = spec.linux().as_ref().unwrap().resources().as_ref().unwrap();
let spec_network = resources.network().as_ref().unwrap();
// Validate net_cls.classid
let classid_content = fs::read_to_string(&net_cls_path)
.with_context(|| format!("failed to read {:?}", net_cls_path))?;
let expected_classid = spec_network.class_id().unwrap();
let actual_classid: u32 = classid_content
.trim()
.parse()
.with_context(|| format!("could not parse {:?}", classid_content.trim()))?;
if expected_classid != actual_classid {
bail!(
"expected {:?} to contain a classid of {}, but the classid was {}",
net_cls_path,
expected_classid,
actual_classid
);
}
// Validate net_prio.ifpriomap
let ifpriomap_content = fs::read_to_string(&net_prio_path)
.with_context(|| format!("failed to read {:?}", net_prio_path))?;
let expected_priorities = spec_network.priorities().as_ref().unwrap();
for priority in expected_priorities {
let expected_entry = format!("{} {}", priority.name(), priority.priority());
if !ifpriomap_content.contains(&expected_entry) {
bail!(
"expected {:?} to contain an entry '{}', but it was not found",
net_prio_path,
expected_entry
);
}
}
Ok(())
}
fn net_cls_path(base_path: PathBuf, cgroup_name: &str) -> PathBuf {
base_path
.join("runtime-test")
.join(cgroup_name)
.join("net_cls.classid")
}
fn net_prio_path(base_path: PathBuf, cgroup_name: &str) -> PathBuf {
base_path
.join("runtime-test")
.join(cgroup_name)
.join("net_prio.ifpriomap")
}
fn can_run() -> bool {
// Ensure the expected network interfaces exist on the system running the test
let iface_exists = get_network_interfaces().is_some();