cgroups_rs/fs/
net_cls.rs

1// Copyright (c) 2018 Levente Kurusa
2//
3// SPDX-License-Identifier: Apache-2.0 or MIT
4//
5
6//! This module contains the implementation of the `net_cls` cgroup subsystem.
7//!
8//! See the Kernel's documentation for more information about this subsystem, found at:
9//!  [Documentation/cgroup-v1/net_cls.txt](https://www.kernel.org/doc/Documentation/cgroup-v1/net_cls.txt)
10use std::io::Write;
11use std::path::PathBuf;
12
13use crate::fs::error::ErrorKind::*;
14use crate::fs::error::*;
15
16use crate::fs::read_u64_from;
17use crate::fs::{
18    ControllIdentifier, ControllerInternal, Controllers, NetworkResources, Resources, Subsystem,
19};
20
21/// A controller that allows controlling the `net_cls` subsystem of a Cgroup.
22///
23/// In esssence, using the `net_cls` controller, one can attach a custom class to the network
24/// packets emitted by the control group's tasks. This can then later be used in iptables to have
25/// custom firewall rules, QoS, etc.
26#[derive(Debug, Clone)]
27pub struct NetClsController {
28    base: PathBuf,
29    path: PathBuf,
30}
31
32impl ControllerInternal for NetClsController {
33    fn control_type(&self) -> Controllers {
34        Controllers::NetCls
35    }
36    fn get_path(&self) -> &PathBuf {
37        &self.path
38    }
39    fn get_path_mut(&mut self) -> &mut PathBuf {
40        &mut self.path
41    }
42    fn get_base(&self) -> &PathBuf {
43        &self.base
44    }
45
46    fn apply(&self, res: &Resources) -> Result<()> {
47        // get the resources that apply to this controller
48        let res: &NetworkResources = &res.network;
49
50        update_and_test!(self, set_class, res.class_id, get_class);
51
52        Ok(())
53    }
54}
55
56impl ControllIdentifier for NetClsController {
57    fn controller_type() -> Controllers {
58        Controllers::NetCls
59    }
60}
61
62impl<'a> From<&'a Subsystem> for &'a NetClsController {
63    fn from(sub: &'a Subsystem) -> &'a NetClsController {
64        unsafe {
65            match sub {
66                Subsystem::NetCls(c) => c,
67                _ => {
68                    assert_eq!(1, 0);
69                    let v = std::mem::MaybeUninit::uninit();
70                    v.assume_init()
71                }
72            }
73        }
74    }
75}
76
77impl NetClsController {
78    /// Constructs a new `NetClsController` with `root` serving as the root of the control group.
79    pub fn new(point: PathBuf, root: PathBuf) -> Self {
80        Self {
81            base: root,
82            path: point,
83        }
84    }
85
86    /// Set the network class id of the outgoing packets of the control group's tasks.
87    pub fn set_class(&self, class: u64) -> Result<()> {
88        self.open_path("net_cls.classid", true)
89            .and_then(|mut file| {
90                let s = format!("{:#08X}", class);
91                file.write_all(s.as_ref()).map_err(|e| {
92                    Error::with_cause(WriteFailed("net_cls.classid".to_string(), s), e)
93                })
94            })
95    }
96
97    /// Get the network class id of the outgoing packets of the control group's tasks.
98    pub fn get_class(&self) -> Result<u64> {
99        self.open_path("net_cls.classid", false)
100            .and_then(read_u64_from)
101    }
102}