rtnetlink/link/
macsec.rs

1// SPDX-License-Identifier: MIT
2
3use netlink_packet_core::DefaultNla;
4use netlink_packet_route::link::{
5    InfoMacSec, MacSecCipherId, MacSecOffload, MacSecValidate,
6};
7
8use crate::{
9    link::LinkMessageBuilder,
10    packet_route::link::{InfoData, InfoKind},
11};
12
13/// Represent MACsec interface.
14/// Example code on creating a MACsec interface
15/// ```no_run
16/// use rtnetlink::{new_connection, LinkMacSec};
17///
18/// #[tokio::main]
19/// async fn main() -> Result<(), String> {
20///     let (connection, handle, _) = new_connection().unwrap();
21///     tokio::spawn(connection);
22///
23///     handle
24///         .link()
25///         .add(
26///             LinkMacSec::new("macsec0", 10)
27///                 .up()
28///                 .build(),
29///         )
30///         .execute()
31///         .await
32///         .map_err(|e| format!("{e}"))
33/// }
34/// ```
35///
36/// Please check LinkMessageBuilder::<LinkMacSec> for more detail.
37#[derive(Debug)]
38pub struct LinkMacSec;
39
40impl LinkMacSec {
41    /// Wrapper of `LinkMessageBuilder::<LinkMacSec>::new().link().mode()`
42    pub fn new(name: &str, base_iface_index: u32) -> LinkMessageBuilder<Self> {
43        LinkMessageBuilder::<LinkMacSec>::new(name).link(base_iface_index)
44    }
45}
46
47impl LinkMessageBuilder<LinkMacSec> {
48    /// Create [LinkMessageBuilder] for MACSEC
49    pub fn new(name: &str) -> Self {
50        LinkMessageBuilder::<LinkMacSec>::new_with_info_kind(InfoKind::MacSec)
51            .name(name.to_string())
52    }
53
54    pub fn append_info_data(mut self, info: InfoMacSec) -> Self {
55        if let InfoData::MacSec(infos) = self
56            .info_data
57            .get_or_insert_with(|| InfoData::MacSec(Vec::new()))
58        {
59            infos.push(info);
60        }
61        self
62    }
63
64    pub fn sci(self, sci: u64) -> Self {
65        self.append_info_data(InfoMacSec::Sci(sci))
66    }
67
68    pub fn port(self, port: u16) -> Self {
69        self.append_info_data(InfoMacSec::Port(port))
70    }
71
72    pub fn icv_len(self, icv_len: u8) -> Self {
73        self.append_info_data(InfoMacSec::IcvLen(icv_len))
74    }
75
76    pub fn cipher_suite(self, cipher_suite: MacSecCipherId) -> Self {
77        self.append_info_data(InfoMacSec::CipherSuite(cipher_suite))
78    }
79
80    pub fn window(self, window: u32) -> Self {
81        self.append_info_data(InfoMacSec::Window(window))
82    }
83
84    pub fn encoding_sa(self, encoding_sa: u8) -> Self {
85        self.append_info_data(InfoMacSec::EncodingSa(encoding_sa))
86    }
87
88    pub fn encrypt(self, encrypt: bool) -> Self {
89        self.append_info_data(InfoMacSec::Encrypt(if encrypt { 1 } else { 0 }))
90    }
91
92    pub fn protect(self, protect: bool) -> Self {
93        self.append_info_data(InfoMacSec::Protect(if protect { 1 } else { 0 }))
94    }
95
96    pub fn inc_sci(self, inc_sci: bool) -> Self {
97        self.append_info_data(InfoMacSec::IncSci(if inc_sci { 1 } else { 0 }))
98    }
99
100    pub fn es(self, es: bool) -> Self {
101        self.append_info_data(InfoMacSec::Es(if es { 1 } else { 0 }))
102    }
103
104    pub fn scb(self, scb: bool) -> Self {
105        self.append_info_data(InfoMacSec::Scb(if scb { 1 } else { 0 }))
106    }
107
108    pub fn replay_protect(self, replay_protect: bool) -> Self {
109        self.append_info_data(InfoMacSec::ReplayProtect(if replay_protect {
110            1
111        } else {
112            0
113        }))
114    }
115
116    pub fn validation(self, validation: MacSecValidate) -> Self {
117        self.append_info_data(InfoMacSec::Validation(validation))
118    }
119
120    pub fn offload(self, offload: MacSecOffload) -> Self {
121        self.append_info_data(InfoMacSec::Offload(offload))
122    }
123
124    pub fn other(self, other: DefaultNla) -> Self {
125        self.append_info_data(InfoMacSec::Other(other))
126    }
127}