1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
// SPDX-License-Identifier: MIT

use super::{
    QDiscDelRequest,
    QDiscGetRequest,
    QDiscNewRequest,
    TrafficChainGetRequest,
    TrafficClassGetRequest,
    TrafficFilterGetRequest,
    TrafficFilterNewRequest,
};

use crate::{
    packet::{TcMessage, NLM_F_CREATE, NLM_F_EXCL, NLM_F_REPLACE},
    Handle,
};

pub struct QDiscHandle(Handle);

impl QDiscHandle {
    pub fn new(handle: Handle) -> Self {
        QDiscHandle(handle)
    }

    /// Retrieve the list of qdisc (equivalent to `tc qdisc show`)
    pub fn get(&mut self) -> QDiscGetRequest {
        QDiscGetRequest::new(self.0.clone())
    }

    /// Create a new qdisc, don't replace if the object already exists.
    /// ( equivalent to `tc qdisc add dev STRING`)
    pub fn add(&mut self, index: i32) -> QDiscNewRequest {
        let msg = TcMessage::with_index(index);
        QDiscNewRequest::new(self.0.clone(), msg, NLM_F_EXCL | NLM_F_CREATE)
    }

    /// Change the qdisc, the handle cannot be changed and neither can the parent.
    /// In other words, change cannot move a node.
    /// ( equivalent to `tc qdisc change dev STRING`)
    pub fn change(&mut self, index: i32) -> QDiscNewRequest {
        let msg = TcMessage::with_index(index);
        QDiscNewRequest::new(self.0.clone(), msg, 0)
    }

    /// Replace existing matching qdisc, create qdisc if it doesn't already exist.
    /// ( equivalent to `tc qdisc replace dev STRING`)
    pub fn replace(&mut self, index: i32) -> QDiscNewRequest {
        let msg = TcMessage::with_index(index);
        QDiscNewRequest::new(self.0.clone(), msg, NLM_F_CREATE | NLM_F_REPLACE)
    }

    /// Performs a replace where the node must exist already.
    /// ( equivalent to `tc qdisc link dev STRING`)
    pub fn link(&mut self, index: i32) -> QDiscNewRequest {
        let msg = TcMessage::with_index(index);
        QDiscNewRequest::new(self.0.clone(), msg, NLM_F_REPLACE)
    }

    /// Delete the qdisc ( equivalent to `tc qdisc del dev STRING`)
    pub fn del(&mut self, index: i32) -> QDiscDelRequest {
        let msg = TcMessage::with_index(index);
        QDiscDelRequest::new(self.0.clone(), msg)
    }
}

pub struct TrafficClassHandle {
    handle: Handle,
    ifindex: i32,
}

impl TrafficClassHandle {
    pub fn new(handle: Handle, ifindex: i32) -> Self {
        TrafficClassHandle { handle, ifindex }
    }

    /// Retrieve the list of traffic class (equivalent to
    /// `tc class show dev <interface_name>`)
    pub fn get(&mut self) -> TrafficClassGetRequest {
        TrafficClassGetRequest::new(self.handle.clone(), self.ifindex)
    }
}

pub struct TrafficFilterHandle {
    handle: Handle,
    ifindex: i32,
}

impl TrafficFilterHandle {
    pub fn new(handle: Handle, ifindex: i32) -> Self {
        TrafficFilterHandle { handle, ifindex }
    }

    /// Retrieve the list of filter (equivalent to
    /// `tc filter show dev <iface_name>`)
    pub fn get(&mut self) -> TrafficFilterGetRequest {
        TrafficFilterGetRequest::new(self.handle.clone(), self.ifindex)
    }

    /// Add a filter to a node, don't replace if the object already exists.
    /// ( equivalent to `tc filter add dev STRING`)
    pub fn add(&mut self) -> TrafficFilterNewRequest {
        TrafficFilterNewRequest::new(self.handle.clone(), self.ifindex, NLM_F_EXCL | NLM_F_CREATE)
    }

    /// Change the filter, the handle cannot be changed and neither can the parent.
    /// In other words, change cannot move a node.
    /// ( equivalent to `tc filter change dev STRING`)
    pub fn change(&mut self) -> TrafficFilterNewRequest {
        TrafficFilterNewRequest::new(self.handle.clone(), self.ifindex, 0)
    }

    /// Replace existing matching filter, create filter if it doesn't already exist.
    /// ( equivalent to `tc filter replace dev STRING`)
    pub fn replace(&mut self) -> TrafficFilterNewRequest {
        TrafficFilterNewRequest::new(self.handle.clone(), self.ifindex, NLM_F_CREATE)
    }
}

pub struct TrafficChainHandle {
    handle: Handle,
    ifindex: i32,
}

impl TrafficChainHandle {
    pub fn new(handle: Handle, ifindex: i32) -> Self {
        TrafficChainHandle { handle, ifindex }
    }

    /// Retrieve the list of chain (equivalent to
    /// `tc chain show dev <iface_name>`)
    pub fn get(&mut self) -> TrafficChainGetRequest {
        TrafficChainGetRequest::new(self.handle.clone(), self.ifindex)
    }
}