netlink_packet_route/link/link_info/
macsec.rs1use netlink_packet_core::{
4 emit_u16, emit_u32, emit_u64, parse_u16, parse_u32, parse_u64, parse_u8,
5 DecodeError, DefaultNla, ErrorContext, Nla, NlaBuffer, Parseable,
6};
7
8const IFLA_MACSEC_SCI: u16 = 1;
9const IFLA_MACSEC_PORT: u16 = 2;
10const IFLA_MACSEC_ICV_LEN: u16 = 3;
11const IFLA_MACSEC_CIPHER_SUITE: u16 = 4;
12const IFLA_MACSEC_WINDOW: u16 = 5;
13const IFLA_MACSEC_ENCODING_SA: u16 = 6;
14const IFLA_MACSEC_ENCRYPT: u16 = 7;
15const IFLA_MACSEC_PROTECT: u16 = 8;
16const IFLA_MACSEC_INC_SCI: u16 = 9;
17const IFLA_MACSEC_ES: u16 = 10;
18const IFLA_MACSEC_SCB: u16 = 11;
19const IFLA_MACSEC_REPLAY_PROTECT: u16 = 12;
20const IFLA_MACSEC_VALIDATION: u16 = 13;
21const IFLA_MACSEC_OFFLOAD: u16 = 15;
23const MACSEC_VALIDATE_DISABLED: u8 = 0;
24const MACSEC_VALIDATE_CHECK: u8 = 1;
25const MACSEC_VALIDATE_STRICT: u8 = 2;
26const MACSEC_OFFLOAD_OFF: u8 = 0;
27const MACSEC_OFFLOAD_PHY: u8 = 1;
28const MACSEC_OFFLOAD_MAC: u8 = 2;
29const MACSEC_CIPHER_ID_GCM_AES_128: u64 = 0x0080C20001000001;
30const MACSEC_CIPHER_ID_GCM_AES_256: u64 = 0x0080C20001000002;
31const MACSEC_CIPHER_ID_GCM_AES_XPN_128: u64 = 0x0080C20001000003;
32const MACSEC_CIPHER_ID_GCM_AES_XPN_256: u64 = 0x0080C20001000004;
33const MACSEC_DEFAULT_CIPHER_ID: u64 = 0x0080020001000001;
34
35#[derive(Debug, PartialEq, Eq, Clone, Copy)]
36#[non_exhaustive]
37pub enum MacSecCipherId {
38 #[deprecated]
39 DefaultGcmAes128,
40 GcmAes128,
41 GcmAes256,
42 GcmAesXpn128,
43 GcmAesXpn256,
44 Other(u64),
45}
46
47impl From<u64> for MacSecCipherId {
48 fn from(d: u64) -> Self {
49 match d {
50 #[allow(deprecated)]
51 MACSEC_DEFAULT_CIPHER_ID => Self::DefaultGcmAes128,
52 MACSEC_CIPHER_ID_GCM_AES_128 => Self::GcmAes128,
53 MACSEC_CIPHER_ID_GCM_AES_256 => Self::GcmAes256,
54 MACSEC_CIPHER_ID_GCM_AES_XPN_128 => Self::GcmAesXpn128,
55 MACSEC_CIPHER_ID_GCM_AES_XPN_256 => Self::GcmAesXpn256,
56 _ => Self::Other(d),
57 }
58 }
59}
60
61impl From<MacSecCipherId> for u64 {
62 fn from(d: MacSecCipherId) -> Self {
63 match d {
64 #[allow(deprecated)]
65 MacSecCipherId::DefaultGcmAes128 => MACSEC_DEFAULT_CIPHER_ID,
66 MacSecCipherId::GcmAes128 => MACSEC_CIPHER_ID_GCM_AES_128,
67 MacSecCipherId::GcmAes256 => MACSEC_CIPHER_ID_GCM_AES_256,
68 MacSecCipherId::GcmAesXpn128 => MACSEC_CIPHER_ID_GCM_AES_XPN_128,
69 MacSecCipherId::GcmAesXpn256 => MACSEC_CIPHER_ID_GCM_AES_XPN_256,
70 MacSecCipherId::Other(value) => value,
71 }
72 }
73}
74
75#[derive(Debug, PartialEq, Eq, Clone, Copy)]
76#[non_exhaustive]
77pub enum MacSecValidate {
78 Disabled,
79 Check,
80 Strict,
81 Other(u8),
82}
83
84impl From<u8> for MacSecValidate {
85 fn from(d: u8) -> Self {
86 match d {
87 MACSEC_VALIDATE_DISABLED => Self::Disabled,
88 MACSEC_VALIDATE_CHECK => Self::Check,
89 MACSEC_VALIDATE_STRICT => Self::Strict,
90 _ => Self::Other(d),
91 }
92 }
93}
94
95impl From<MacSecValidate> for u8 {
96 fn from(d: MacSecValidate) -> Self {
97 match d {
98 MacSecValidate::Disabled => MACSEC_VALIDATE_DISABLED,
99 MacSecValidate::Check => MACSEC_VALIDATE_CHECK,
100 MacSecValidate::Strict => MACSEC_VALIDATE_STRICT,
101 MacSecValidate::Other(value) => value,
102 }
103 }
104}
105
106#[derive(Debug, PartialEq, Eq, Clone, Copy)]
107#[non_exhaustive]
108pub enum MacSecOffload {
109 Off,
110 Phy,
111 Mac,
112 Other(u8),
113}
114
115impl From<u8> for MacSecOffload {
116 fn from(d: u8) -> Self {
117 match d {
118 MACSEC_OFFLOAD_OFF => Self::Off,
119 MACSEC_OFFLOAD_PHY => Self::Phy,
120 MACSEC_OFFLOAD_MAC => Self::Mac,
121 _ => Self::Other(d),
122 }
123 }
124}
125
126impl From<MacSecOffload> for u8 {
127 fn from(d: MacSecOffload) -> Self {
128 match d {
129 MacSecOffload::Off => MACSEC_OFFLOAD_OFF,
130 MacSecOffload::Phy => MACSEC_OFFLOAD_PHY,
131 MacSecOffload::Mac => MACSEC_OFFLOAD_MAC,
132 MacSecOffload::Other(value) => value,
133 }
134 }
135}
136
137#[derive(Debug, PartialEq, Eq, Clone)]
138#[non_exhaustive]
139pub enum InfoMacSec {
140 Sci(u64),
141 Port(u16),
142 IcvLen(u8),
143 CipherSuite(MacSecCipherId),
144 Window(u32),
145 EncodingSa(u8),
146 Encrypt(u8),
147 Protect(u8),
148 IncSci(u8),
149 Es(u8),
150 Scb(u8),
151 ReplayProtect(u8),
152 Validation(MacSecValidate),
153 Offload(MacSecOffload),
154 Other(DefaultNla),
155}
156
157impl Nla for InfoMacSec {
158 fn value_len(&self) -> usize {
159 use self::InfoMacSec::*;
160 match self {
161 Sci(_) | CipherSuite(_) => 8,
162 Window(_) => 4,
163 Port(_) => 2,
164 IcvLen(_) | EncodingSa(_) | Encrypt(_) | Protect(_) | IncSci(_)
165 | Es(_) | Scb(_) | ReplayProtect(_) | Validation(_)
166 | Offload(_) => 1,
167 Other(nla) => nla.value_len(),
168 }
169 }
170
171 fn emit_value(&self, buffer: &mut [u8]) {
172 use self::InfoMacSec::*;
173 match self {
174 Sci(value) => emit_u64(buffer, *value).unwrap(),
175 CipherSuite(value) => emit_u64(buffer, (*value).into()).unwrap(),
176 Window(value) => emit_u32(buffer, *value).unwrap(),
177 Port(value) => emit_u16(buffer, *value).unwrap(),
178 IcvLen(value) | EncodingSa(value) | Encrypt(value)
179 | Protect(value) | IncSci(value) | Es(value) | Scb(value)
180 | ReplayProtect(value) => buffer[0] = *value,
181 Offload(value) => buffer[0] = (*value).into(),
182 Validation(value) => buffer[0] = (*value).into(),
183 Other(nla) => nla.emit_value(buffer),
184 }
185 }
186
187 fn kind(&self) -> u16 {
188 use self::InfoMacSec::*;
189 match self {
190 Sci(_) => IFLA_MACSEC_SCI,
191 Port(_) => IFLA_MACSEC_PORT,
192 IcvLen(_) => IFLA_MACSEC_ICV_LEN,
193 CipherSuite(_) => IFLA_MACSEC_CIPHER_SUITE,
194 Window(_) => IFLA_MACSEC_WINDOW,
195 EncodingSa(_) => IFLA_MACSEC_ENCODING_SA,
196 Encrypt(_) => IFLA_MACSEC_ENCRYPT,
197 Protect(_) => IFLA_MACSEC_PROTECT,
198 IncSci(_) => IFLA_MACSEC_INC_SCI,
199 Es(_) => IFLA_MACSEC_ES,
200 Scb(_) => IFLA_MACSEC_SCB,
201 ReplayProtect(_) => IFLA_MACSEC_REPLAY_PROTECT,
202 Validation(_) => IFLA_MACSEC_VALIDATION,
203 Offload(_) => IFLA_MACSEC_OFFLOAD,
204 Other(nla) => nla.kind(),
205 }
206 }
207}
208
209impl<'a, T: AsRef<[u8]> + ?Sized> Parseable<NlaBuffer<&'a T>> for InfoMacSec {
210 fn parse(buf: &NlaBuffer<&'a T>) -> Result<Self, DecodeError> {
211 use self::InfoMacSec::*;
212 let payload = buf.value();
213 Ok(match buf.kind() {
214 IFLA_MACSEC_SCI => {
215 Sci(parse_u64(payload)
216 .context("invalid IFLA_MACSEC_SCI value")?)
217 }
218 IFLA_MACSEC_PORT => Port(
219 parse_u16(payload).context("invalid IFLA_MACSEC_PORT value")?,
220 ),
221 IFLA_MACSEC_ICV_LEN => IcvLen(
222 parse_u8(payload)
223 .context("invalid IFLA_MACSEC_ICV_LEN value")?,
224 ),
225 IFLA_MACSEC_CIPHER_SUITE => CipherSuite(
226 parse_u64(payload)
227 .context("invalid IFLA_MACSEC_CIPHER_SUITE value")?
228 .into(),
229 ),
230 IFLA_MACSEC_WINDOW => Window(
231 parse_u32(payload)
232 .context("invalid IFLA_MACSEC_WINDOW value")?,
233 ),
234 IFLA_MACSEC_ENCODING_SA => EncodingSa(
235 parse_u8(payload)
236 .context("invalid IFLA_MACSEC_ENCODING_SA value")?,
237 ),
238 IFLA_MACSEC_ENCRYPT => Encrypt(
239 parse_u8(payload)
240 .context("invalid IFLA_MACSEC_ENCRYPT value")?,
241 ),
242 IFLA_MACSEC_PROTECT => Protect(
243 parse_u8(payload)
244 .context("invalid IFLA_MACSEC_PROTECT value")?,
245 ),
246 IFLA_MACSEC_INC_SCI => IncSci(
247 parse_u8(payload)
248 .context("invalid IFLA_MACSEC_INC_SCI value")?,
249 ),
250 IFLA_MACSEC_ES => {
251 Es(parse_u8(payload).context("invalid IFLA_MACSEC_ES value")?)
252 }
253 IFLA_MACSEC_SCB => {
254 Scb(parse_u8(payload)
255 .context("invalid IFLA_MACSEC_SCB value")?)
256 }
257 IFLA_MACSEC_REPLAY_PROTECT => ReplayProtect(
258 parse_u8(payload)
259 .context("invalid IFLA_MACSEC_REPLAY_PROTECT value")?,
260 ),
261 IFLA_MACSEC_VALIDATION => Validation(
262 parse_u8(payload)
263 .context("invalid IFLA_MACSEC_VALIDATION value")?
264 .into(),
265 ),
266 IFLA_MACSEC_OFFLOAD => Offload(
267 parse_u8(payload)
268 .context("invalid IFLA_MACSEC_OFFLOAD value")?
269 .into(),
270 ),
271 kind => Other(
272 DefaultNla::parse(buf)
273 .context(format!("unknown NLA type {kind}"))?,
274 ),
275 })
276 }
277}