1#![doc = "OVS flow configuration over generic netlink.\n"]
2#![allow(clippy::all)]
3#![allow(unused_imports)]
4#![allow(unused_assignments)]
5#![allow(non_snake_case)]
6#![allow(unused_variables)]
7#![allow(irrefutable_let_patterns)]
8#![allow(unreachable_code)]
9#![allow(unreachable_patterns)]
10use crate::builtin::{BuiltinBitfield32, BuiltinNfgenmsg, Nlmsghdr, PushDummy};
11use crate::{
12 consts,
13 traits::{NetlinkRequest, Protocol},
14 utils::*,
15};
16pub const PROTONAME: &str = "ovs_flow";
17pub const PROTONAME_CSTR: &CStr = c"ovs_flow";
18#[doc = "Enum - defines an integer enumeration, with values for each entry incrementing by 1, (e.g. 0, 1, 2, 3)"]
19#[derive(Debug, Clone, Copy)]
20pub enum OvsFragType {
21 #[doc = "Packet is not a fragment.\n"]
22 None = 0,
23 #[doc = "Packet is a fragment with offset 0.\n"]
24 First = 1,
25 #[doc = "Packet is a fragment with nonzero offset.\n"]
26 Later = 2,
27 Any = 255,
28}
29impl OvsFragType {
30 pub fn from_value(value: u64) -> Option<Self> {
31 Some(match value {
32 0 => Self::None,
33 1 => Self::First,
34 2 => Self::Later,
35 255 => Self::Any,
36 _ => return None,
37 })
38 }
39}
40#[doc = "Flags - defines an integer enumeration, with values for each entry occupying a bit, starting from bit 0, (e.g. 1, 2, 4, 8)"]
41#[derive(Debug, Clone, Copy)]
42pub enum OvsUfidFlags {
43 OmitKey = 1 << 0,
44 OmitMask = 1 << 1,
45 OmitActions = 1 << 2,
46}
47impl OvsUfidFlags {
48 pub fn from_value(value: u64) -> Option<Self> {
49 Some(match value {
50 n if n == 1 << 0 => Self::OmitKey,
51 n if n == 1 << 1 => Self::OmitMask,
52 n if n == 1 << 2 => Self::OmitActions,
53 _ => return None,
54 })
55 }
56}
57#[doc = "Data path hash algorithm for computing Datapath hash. The algorithm type\nonly specifies the fields in a flow will be used as part of the hash.\nEach datapath is free to use its own hash algorithm. The hash value will\nbe opaque to the user space daemon.\n"]
58#[doc = "Enum - defines an integer enumeration, with values for each entry incrementing by 1, (e.g. 0, 1, 2, 3)"]
59#[derive(Debug, Clone, Copy)]
60pub enum OvsHashAlg {
61 OvsHashAlgL4 = 0,
62}
63impl OvsHashAlg {
64 pub fn from_value(value: u64) -> Option<Self> {
65 Some(match value {
66 0 => Self::OvsHashAlgL4,
67 _ => return None,
68 })
69 }
70}
71#[doc = "Flags - defines an integer enumeration, with values for each entry occupying a bit, starting from bit 0, (e.g. 1, 2, 4, 8)"]
72#[derive(Debug, Clone, Copy)]
73pub enum CtStateFlags {
74 #[doc = "Beginning of a new connection.\n"]
75 New = 1 << 0,
76 #[doc = "Part of an existing connenction\n"]
77 Established = 1 << 1,
78 #[doc = "Related to an existing connection.\n"]
79 Related = 1 << 2,
80 #[doc = "Flow is in the reply direction.\n"]
81 ReplyDir = 1 << 3,
82 #[doc = "Could not track the connection.\n"]
83 Invalid = 1 << 4,
84 #[doc = "Conntrack has occurred.\n"]
85 Tracked = 1 << 5,
86 #[doc = "Packet\\'s source address/port was mangled by NAT.\n"]
87 SrcNat = 1 << 6,
88 #[doc = "Packet\\'s destination address/port was mangled by NAT.\n"]
89 DstNat = 1 << 7,
90}
91impl CtStateFlags {
92 pub fn from_value(value: u64) -> Option<Self> {
93 Some(match value {
94 n if n == 1 << 0 => Self::New,
95 n if n == 1 << 1 => Self::Established,
96 n if n == 1 << 2 => Self::Related,
97 n if n == 1 << 3 => Self::ReplyDir,
98 n if n == 1 << 4 => Self::Invalid,
99 n if n == 1 << 5 => Self::Tracked,
100 n if n == 1 << 6 => Self::SrcNat,
101 n if n == 1 << 7 => Self::DstNat,
102 _ => return None,
103 })
104 }
105}
106#[derive(Debug)]
107#[doc = "Header for OVS Generic Netlink messages.\n"]
108#[repr(C, packed(4))]
109pub struct OvsHeader {
110 #[doc = "ifindex of local port for datapath (0 to make a request not specific to\na datapath).\n"]
111 pub dp_ifindex: u32,
112}
113impl Clone for OvsHeader {
114 fn clone(&self) -> Self {
115 Self::new_from_array(*self.as_array())
116 }
117}
118#[doc = "Create zero-initialized struct"]
119impl Default for OvsHeader {
120 fn default() -> Self {
121 Self::new()
122 }
123}
124impl OvsHeader {
125 #[doc = "Create zero-initialized struct"]
126 pub fn new() -> Self {
127 Self::new_from_array([0u8; Self::len()])
128 }
129 #[doc = "Copy from contents from slice"]
130 pub fn new_from_slice(other: &[u8]) -> Option<Self> {
131 if other.len() != Self::len() {
132 return None;
133 }
134 let mut buf = [0u8; Self::len()];
135 buf.clone_from_slice(other);
136 Some(Self::new_from_array(buf))
137 }
138 #[doc = "Copy from contents from another slice, padding with zeros or truncating when needed"]
139 pub fn new_from_zeroed(other: &[u8]) -> Self {
140 let mut buf = [0u8; Self::len()];
141 let len = buf.len().min(other.len());
142 buf[..len].clone_from_slice(&other[..len]);
143 Self::new_from_array(buf)
144 }
145 pub fn new_from_array(buf: [u8; 4usize]) -> Self {
146 unsafe { std::mem::transmute(buf) }
147 }
148 pub fn as_slice(&self) -> &[u8] {
149 unsafe {
150 let ptr: *const u8 = std::mem::transmute(self as *const Self);
151 std::slice::from_raw_parts(ptr, Self::len())
152 }
153 }
154 pub fn from_slice(buf: &[u8]) -> &Self {
155 assert!(buf.len() >= Self::len());
156 assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
157 unsafe { std::mem::transmute(buf.as_ptr()) }
158 }
159 pub fn as_array(&self) -> &[u8; 4usize] {
160 unsafe { std::mem::transmute(self) }
161 }
162 pub fn from_array(buf: &[u8; 4usize]) -> &Self {
163 assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
164 unsafe { std::mem::transmute(buf) }
165 }
166 pub fn into_array(self) -> [u8; 4usize] {
167 unsafe { std::mem::transmute(self) }
168 }
169 pub const fn len() -> usize {
170 const _: () = assert!(std::mem::size_of::<OvsHeader>() == 4usize);
171 4usize
172 }
173}
174#[repr(C, packed(4))]
175pub struct OvsFlowStats {
176 #[doc = "Number of matched packets.\n"]
177 pub n_packets: u64,
178 #[doc = "Number of matched bytes.\n"]
179 pub n_bytes: u64,
180}
181impl Clone for OvsFlowStats {
182 fn clone(&self) -> Self {
183 Self::new_from_array(*self.as_array())
184 }
185}
186#[doc = "Create zero-initialized struct"]
187impl Default for OvsFlowStats {
188 fn default() -> Self {
189 Self::new()
190 }
191}
192impl OvsFlowStats {
193 #[doc = "Create zero-initialized struct"]
194 pub fn new() -> Self {
195 Self::new_from_array([0u8; Self::len()])
196 }
197 #[doc = "Copy from contents from slice"]
198 pub fn new_from_slice(other: &[u8]) -> Option<Self> {
199 if other.len() != Self::len() {
200 return None;
201 }
202 let mut buf = [0u8; Self::len()];
203 buf.clone_from_slice(other);
204 Some(Self::new_from_array(buf))
205 }
206 #[doc = "Copy from contents from another slice, padding with zeros or truncating when needed"]
207 pub fn new_from_zeroed(other: &[u8]) -> Self {
208 let mut buf = [0u8; Self::len()];
209 let len = buf.len().min(other.len());
210 buf[..len].clone_from_slice(&other[..len]);
211 Self::new_from_array(buf)
212 }
213 pub fn new_from_array(buf: [u8; 16usize]) -> Self {
214 unsafe { std::mem::transmute(buf) }
215 }
216 pub fn as_slice(&self) -> &[u8] {
217 unsafe {
218 let ptr: *const u8 = std::mem::transmute(self as *const Self);
219 std::slice::from_raw_parts(ptr, Self::len())
220 }
221 }
222 pub fn from_slice(buf: &[u8]) -> &Self {
223 assert!(buf.len() >= Self::len());
224 assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
225 unsafe { std::mem::transmute(buf.as_ptr()) }
226 }
227 pub fn as_array(&self) -> &[u8; 16usize] {
228 unsafe { std::mem::transmute(self) }
229 }
230 pub fn from_array(buf: &[u8; 16usize]) -> &Self {
231 assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
232 unsafe { std::mem::transmute(buf) }
233 }
234 pub fn into_array(self) -> [u8; 16usize] {
235 unsafe { std::mem::transmute(self) }
236 }
237 pub const fn len() -> usize {
238 const _: () = assert!(std::mem::size_of::<OvsFlowStats>() == 16usize);
239 16usize
240 }
241}
242impl std::fmt::Debug for OvsFlowStats {
243 fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
244 fmt.debug_struct("OvsFlowStats")
245 .field("n_packets", &{ self.n_packets })
246 .field("n_bytes", &{ self.n_bytes })
247 .finish()
248 }
249}
250#[derive(Debug)]
251#[repr(C, packed(4))]
252pub struct OvsKeyEthernet {
253 pub eth_src: [u8; 6usize],
254 pub eth_dst: [u8; 6usize],
255}
256impl Clone for OvsKeyEthernet {
257 fn clone(&self) -> Self {
258 Self::new_from_array(*self.as_array())
259 }
260}
261#[doc = "Create zero-initialized struct"]
262impl Default for OvsKeyEthernet {
263 fn default() -> Self {
264 Self::new()
265 }
266}
267impl OvsKeyEthernet {
268 #[doc = "Create zero-initialized struct"]
269 pub fn new() -> Self {
270 Self::new_from_array([0u8; Self::len()])
271 }
272 #[doc = "Copy from contents from slice"]
273 pub fn new_from_slice(other: &[u8]) -> Option<Self> {
274 if other.len() != Self::len() {
275 return None;
276 }
277 let mut buf = [0u8; Self::len()];
278 buf.clone_from_slice(other);
279 Some(Self::new_from_array(buf))
280 }
281 #[doc = "Copy from contents from another slice, padding with zeros or truncating when needed"]
282 pub fn new_from_zeroed(other: &[u8]) -> Self {
283 let mut buf = [0u8; Self::len()];
284 let len = buf.len().min(other.len());
285 buf[..len].clone_from_slice(&other[..len]);
286 Self::new_from_array(buf)
287 }
288 pub fn new_from_array(buf: [u8; 12usize]) -> Self {
289 unsafe { std::mem::transmute(buf) }
290 }
291 pub fn as_slice(&self) -> &[u8] {
292 unsafe {
293 let ptr: *const u8 = std::mem::transmute(self as *const Self);
294 std::slice::from_raw_parts(ptr, Self::len())
295 }
296 }
297 pub fn from_slice(buf: &[u8]) -> &Self {
298 assert!(buf.len() >= Self::len());
299 assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
300 unsafe { std::mem::transmute(buf.as_ptr()) }
301 }
302 pub fn as_array(&self) -> &[u8; 12usize] {
303 unsafe { std::mem::transmute(self) }
304 }
305 pub fn from_array(buf: &[u8; 12usize]) -> &Self {
306 assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
307 unsafe { std::mem::transmute(buf) }
308 }
309 pub fn into_array(self) -> [u8; 12usize] {
310 unsafe { std::mem::transmute(self) }
311 }
312 pub const fn len() -> usize {
313 const _: () = assert!(std::mem::size_of::<OvsKeyEthernet>() == 12usize);
314 12usize
315 }
316}
317#[repr(C, packed(4))]
318pub struct OvsKeyMpls {
319 pub _mpls_lse_be: u32,
320}
321impl Clone for OvsKeyMpls {
322 fn clone(&self) -> Self {
323 Self::new_from_array(*self.as_array())
324 }
325}
326#[doc = "Create zero-initialized struct"]
327impl Default for OvsKeyMpls {
328 fn default() -> Self {
329 Self::new()
330 }
331}
332impl OvsKeyMpls {
333 #[doc = "Create zero-initialized struct"]
334 pub fn new() -> Self {
335 Self::new_from_array([0u8; Self::len()])
336 }
337 #[doc = "Copy from contents from slice"]
338 pub fn new_from_slice(other: &[u8]) -> Option<Self> {
339 if other.len() != Self::len() {
340 return None;
341 }
342 let mut buf = [0u8; Self::len()];
343 buf.clone_from_slice(other);
344 Some(Self::new_from_array(buf))
345 }
346 #[doc = "Copy from contents from another slice, padding with zeros or truncating when needed"]
347 pub fn new_from_zeroed(other: &[u8]) -> Self {
348 let mut buf = [0u8; Self::len()];
349 let len = buf.len().min(other.len());
350 buf[..len].clone_from_slice(&other[..len]);
351 Self::new_from_array(buf)
352 }
353 pub fn new_from_array(buf: [u8; 4usize]) -> Self {
354 unsafe { std::mem::transmute(buf) }
355 }
356 pub fn as_slice(&self) -> &[u8] {
357 unsafe {
358 let ptr: *const u8 = std::mem::transmute(self as *const Self);
359 std::slice::from_raw_parts(ptr, Self::len())
360 }
361 }
362 pub fn from_slice(buf: &[u8]) -> &Self {
363 assert!(buf.len() >= Self::len());
364 assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
365 unsafe { std::mem::transmute(buf.as_ptr()) }
366 }
367 pub fn as_array(&self) -> &[u8; 4usize] {
368 unsafe { std::mem::transmute(self) }
369 }
370 pub fn from_array(buf: &[u8; 4usize]) -> &Self {
371 assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
372 unsafe { std::mem::transmute(buf) }
373 }
374 pub fn into_array(self) -> [u8; 4usize] {
375 unsafe { std::mem::transmute(self) }
376 }
377 pub const fn len() -> usize {
378 const _: () = assert!(std::mem::size_of::<OvsKeyMpls>() == 4usize);
379 4usize
380 }
381 pub fn mpls_lse(&self) -> u32 {
382 u32::from_be(self._mpls_lse_be)
383 }
384 pub fn set_mpls_lse(&mut self, value: u32) {
385 self._mpls_lse_be = value.to_be();
386 }
387}
388impl std::fmt::Debug for OvsKeyMpls {
389 fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
390 fmt.debug_struct("OvsKeyMpls")
391 .field("mpls_lse", &self.mpls_lse())
392 .finish()
393 }
394}
395#[repr(C, packed(4))]
396pub struct OvsKeyIpv4 {
397 pub _ipv4_src_be: u32,
398 pub _ipv4_dst_be: u32,
399 pub ipv4_proto: u8,
400 pub ipv4_tos: u8,
401 pub ipv4_ttl: u8,
402 #[doc = "Associated type: [`OvsFragType`] (enum)"]
403 pub ipv4_frag: u8,
404}
405impl Clone for OvsKeyIpv4 {
406 fn clone(&self) -> Self {
407 Self::new_from_array(*self.as_array())
408 }
409}
410#[doc = "Create zero-initialized struct"]
411impl Default for OvsKeyIpv4 {
412 fn default() -> Self {
413 Self::new()
414 }
415}
416impl OvsKeyIpv4 {
417 #[doc = "Create zero-initialized struct"]
418 pub fn new() -> Self {
419 Self::new_from_array([0u8; Self::len()])
420 }
421 #[doc = "Copy from contents from slice"]
422 pub fn new_from_slice(other: &[u8]) -> Option<Self> {
423 if other.len() != Self::len() {
424 return None;
425 }
426 let mut buf = [0u8; Self::len()];
427 buf.clone_from_slice(other);
428 Some(Self::new_from_array(buf))
429 }
430 #[doc = "Copy from contents from another slice, padding with zeros or truncating when needed"]
431 pub fn new_from_zeroed(other: &[u8]) -> Self {
432 let mut buf = [0u8; Self::len()];
433 let len = buf.len().min(other.len());
434 buf[..len].clone_from_slice(&other[..len]);
435 Self::new_from_array(buf)
436 }
437 pub fn new_from_array(buf: [u8; 12usize]) -> Self {
438 unsafe { std::mem::transmute(buf) }
439 }
440 pub fn as_slice(&self) -> &[u8] {
441 unsafe {
442 let ptr: *const u8 = std::mem::transmute(self as *const Self);
443 std::slice::from_raw_parts(ptr, Self::len())
444 }
445 }
446 pub fn from_slice(buf: &[u8]) -> &Self {
447 assert!(buf.len() >= Self::len());
448 assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
449 unsafe { std::mem::transmute(buf.as_ptr()) }
450 }
451 pub fn as_array(&self) -> &[u8; 12usize] {
452 unsafe { std::mem::transmute(self) }
453 }
454 pub fn from_array(buf: &[u8; 12usize]) -> &Self {
455 assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
456 unsafe { std::mem::transmute(buf) }
457 }
458 pub fn into_array(self) -> [u8; 12usize] {
459 unsafe { std::mem::transmute(self) }
460 }
461 pub const fn len() -> usize {
462 const _: () = assert!(std::mem::size_of::<OvsKeyIpv4>() == 12usize);
463 12usize
464 }
465 pub fn ipv4_src(&self) -> u32 {
466 u32::from_be(self._ipv4_src_be)
467 }
468 pub fn set_ipv4_src(&mut self, value: u32) {
469 self._ipv4_src_be = value.to_be();
470 }
471 pub fn ipv4_dst(&self) -> u32 {
472 u32::from_be(self._ipv4_dst_be)
473 }
474 pub fn set_ipv4_dst(&mut self, value: u32) {
475 self._ipv4_dst_be = value.to_be();
476 }
477}
478impl std::fmt::Debug for OvsKeyIpv4 {
479 fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
480 fmt.debug_struct("OvsKeyIpv4")
481 .field("ipv4_src", &self.ipv4_src())
482 .field("ipv4_dst", &self.ipv4_dst())
483 .field("ipv4_proto", &self.ipv4_proto)
484 .field("ipv4_tos", &self.ipv4_tos)
485 .field("ipv4_ttl", &self.ipv4_ttl)
486 .field(
487 "ipv4_frag",
488 &FormatEnum(self.ipv4_frag.into(), OvsFragType::from_value),
489 )
490 .finish()
491 }
492}
493#[repr(C, packed(4))]
494pub struct OvsKeyIpv6 {
495 pub ipv6_src: [u8; 16usize],
496 pub ipv6_dst: [u8; 16usize],
497 pub _ipv6_label_be: u32,
498 pub ipv6_proto: u8,
499 pub ipv6_tclass: u8,
500 pub ipv6_hlimit: u8,
501 pub ipv6_frag: u8,
502}
503impl Clone for OvsKeyIpv6 {
504 fn clone(&self) -> Self {
505 Self::new_from_array(*self.as_array())
506 }
507}
508#[doc = "Create zero-initialized struct"]
509impl Default for OvsKeyIpv6 {
510 fn default() -> Self {
511 Self::new()
512 }
513}
514impl OvsKeyIpv6 {
515 #[doc = "Create zero-initialized struct"]
516 pub fn new() -> Self {
517 Self::new_from_array([0u8; Self::len()])
518 }
519 #[doc = "Copy from contents from slice"]
520 pub fn new_from_slice(other: &[u8]) -> Option<Self> {
521 if other.len() != Self::len() {
522 return None;
523 }
524 let mut buf = [0u8; Self::len()];
525 buf.clone_from_slice(other);
526 Some(Self::new_from_array(buf))
527 }
528 #[doc = "Copy from contents from another slice, padding with zeros or truncating when needed"]
529 pub fn new_from_zeroed(other: &[u8]) -> Self {
530 let mut buf = [0u8; Self::len()];
531 let len = buf.len().min(other.len());
532 buf[..len].clone_from_slice(&other[..len]);
533 Self::new_from_array(buf)
534 }
535 pub fn new_from_array(buf: [u8; 40usize]) -> Self {
536 unsafe { std::mem::transmute(buf) }
537 }
538 pub fn as_slice(&self) -> &[u8] {
539 unsafe {
540 let ptr: *const u8 = std::mem::transmute(self as *const Self);
541 std::slice::from_raw_parts(ptr, Self::len())
542 }
543 }
544 pub fn from_slice(buf: &[u8]) -> &Self {
545 assert!(buf.len() >= Self::len());
546 assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
547 unsafe { std::mem::transmute(buf.as_ptr()) }
548 }
549 pub fn as_array(&self) -> &[u8; 40usize] {
550 unsafe { std::mem::transmute(self) }
551 }
552 pub fn from_array(buf: &[u8; 40usize]) -> &Self {
553 assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
554 unsafe { std::mem::transmute(buf) }
555 }
556 pub fn into_array(self) -> [u8; 40usize] {
557 unsafe { std::mem::transmute(self) }
558 }
559 pub const fn len() -> usize {
560 const _: () = assert!(std::mem::size_of::<OvsKeyIpv6>() == 40usize);
561 40usize
562 }
563 pub fn ipv6_label(&self) -> u32 {
564 u32::from_be(self._ipv6_label_be)
565 }
566 pub fn set_ipv6_label(&mut self, value: u32) {
567 self._ipv6_label_be = value.to_be();
568 }
569}
570impl std::fmt::Debug for OvsKeyIpv6 {
571 fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
572 fmt.debug_struct("OvsKeyIpv6")
573 .field("ipv6_src", &self.ipv6_src)
574 .field("ipv6_dst", &self.ipv6_dst)
575 .field("ipv6_label", &self.ipv6_label())
576 .field("ipv6_proto", &self.ipv6_proto)
577 .field("ipv6_tclass", &self.ipv6_tclass)
578 .field("ipv6_hlimit", &self.ipv6_hlimit)
579 .field("ipv6_frag", &self.ipv6_frag)
580 .finish()
581 }
582}
583#[derive(Debug)]
584#[repr(C, packed(4))]
585pub struct OvsKeyIpv6Exthdrs {
586 pub hdrs: u16,
587}
588impl Clone for OvsKeyIpv6Exthdrs {
589 fn clone(&self) -> Self {
590 Self::new_from_array(*self.as_array())
591 }
592}
593#[doc = "Create zero-initialized struct"]
594impl Default for OvsKeyIpv6Exthdrs {
595 fn default() -> Self {
596 Self::new()
597 }
598}
599impl OvsKeyIpv6Exthdrs {
600 #[doc = "Create zero-initialized struct"]
601 pub fn new() -> Self {
602 Self::new_from_array([0u8; Self::len()])
603 }
604 #[doc = "Copy from contents from slice"]
605 pub fn new_from_slice(other: &[u8]) -> Option<Self> {
606 if other.len() != Self::len() {
607 return None;
608 }
609 let mut buf = [0u8; Self::len()];
610 buf.clone_from_slice(other);
611 Some(Self::new_from_array(buf))
612 }
613 #[doc = "Copy from contents from another slice, padding with zeros or truncating when needed"]
614 pub fn new_from_zeroed(other: &[u8]) -> Self {
615 let mut buf = [0u8; Self::len()];
616 let len = buf.len().min(other.len());
617 buf[..len].clone_from_slice(&other[..len]);
618 Self::new_from_array(buf)
619 }
620 pub fn new_from_array(buf: [u8; 2usize]) -> Self {
621 unsafe { std::mem::transmute(buf) }
622 }
623 pub fn as_slice(&self) -> &[u8] {
624 unsafe {
625 let ptr: *const u8 = std::mem::transmute(self as *const Self);
626 std::slice::from_raw_parts(ptr, Self::len())
627 }
628 }
629 pub fn from_slice(buf: &[u8]) -> &Self {
630 assert!(buf.len() >= Self::len());
631 assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
632 unsafe { std::mem::transmute(buf.as_ptr()) }
633 }
634 pub fn as_array(&self) -> &[u8; 2usize] {
635 unsafe { std::mem::transmute(self) }
636 }
637 pub fn from_array(buf: &[u8; 2usize]) -> &Self {
638 assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
639 unsafe { std::mem::transmute(buf) }
640 }
641 pub fn into_array(self) -> [u8; 2usize] {
642 unsafe { std::mem::transmute(self) }
643 }
644 pub const fn len() -> usize {
645 const _: () = assert!(std::mem::size_of::<OvsKeyIpv6Exthdrs>() == 2usize);
646 2usize
647 }
648}
649#[repr(C, packed(4))]
650pub struct OvsKeyTcp {
651 pub _tcp_src_be: u16,
652 pub _tcp_dst_be: u16,
653}
654impl Clone for OvsKeyTcp {
655 fn clone(&self) -> Self {
656 Self::new_from_array(*self.as_array())
657 }
658}
659#[doc = "Create zero-initialized struct"]
660impl Default for OvsKeyTcp {
661 fn default() -> Self {
662 Self::new()
663 }
664}
665impl OvsKeyTcp {
666 #[doc = "Create zero-initialized struct"]
667 pub fn new() -> Self {
668 Self::new_from_array([0u8; Self::len()])
669 }
670 #[doc = "Copy from contents from slice"]
671 pub fn new_from_slice(other: &[u8]) -> Option<Self> {
672 if other.len() != Self::len() {
673 return None;
674 }
675 let mut buf = [0u8; Self::len()];
676 buf.clone_from_slice(other);
677 Some(Self::new_from_array(buf))
678 }
679 #[doc = "Copy from contents from another slice, padding with zeros or truncating when needed"]
680 pub fn new_from_zeroed(other: &[u8]) -> Self {
681 let mut buf = [0u8; Self::len()];
682 let len = buf.len().min(other.len());
683 buf[..len].clone_from_slice(&other[..len]);
684 Self::new_from_array(buf)
685 }
686 pub fn new_from_array(buf: [u8; 4usize]) -> Self {
687 unsafe { std::mem::transmute(buf) }
688 }
689 pub fn as_slice(&self) -> &[u8] {
690 unsafe {
691 let ptr: *const u8 = std::mem::transmute(self as *const Self);
692 std::slice::from_raw_parts(ptr, Self::len())
693 }
694 }
695 pub fn from_slice(buf: &[u8]) -> &Self {
696 assert!(buf.len() >= Self::len());
697 assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
698 unsafe { std::mem::transmute(buf.as_ptr()) }
699 }
700 pub fn as_array(&self) -> &[u8; 4usize] {
701 unsafe { std::mem::transmute(self) }
702 }
703 pub fn from_array(buf: &[u8; 4usize]) -> &Self {
704 assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
705 unsafe { std::mem::transmute(buf) }
706 }
707 pub fn into_array(self) -> [u8; 4usize] {
708 unsafe { std::mem::transmute(self) }
709 }
710 pub const fn len() -> usize {
711 const _: () = assert!(std::mem::size_of::<OvsKeyTcp>() == 4usize);
712 4usize
713 }
714 pub fn tcp_src(&self) -> u16 {
715 u16::from_be(self._tcp_src_be)
716 }
717 pub fn set_tcp_src(&mut self, value: u16) {
718 self._tcp_src_be = value.to_be();
719 }
720 pub fn tcp_dst(&self) -> u16 {
721 u16::from_be(self._tcp_dst_be)
722 }
723 pub fn set_tcp_dst(&mut self, value: u16) {
724 self._tcp_dst_be = value.to_be();
725 }
726}
727impl std::fmt::Debug for OvsKeyTcp {
728 fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
729 fmt.debug_struct("OvsKeyTcp")
730 .field("tcp_src", &self.tcp_src())
731 .field("tcp_dst", &self.tcp_dst())
732 .finish()
733 }
734}
735#[repr(C, packed(4))]
736pub struct OvsKeyUdp {
737 pub _udp_src_be: u16,
738 pub _udp_dst_be: u16,
739}
740impl Clone for OvsKeyUdp {
741 fn clone(&self) -> Self {
742 Self::new_from_array(*self.as_array())
743 }
744}
745#[doc = "Create zero-initialized struct"]
746impl Default for OvsKeyUdp {
747 fn default() -> Self {
748 Self::new()
749 }
750}
751impl OvsKeyUdp {
752 #[doc = "Create zero-initialized struct"]
753 pub fn new() -> Self {
754 Self::new_from_array([0u8; Self::len()])
755 }
756 #[doc = "Copy from contents from slice"]
757 pub fn new_from_slice(other: &[u8]) -> Option<Self> {
758 if other.len() != Self::len() {
759 return None;
760 }
761 let mut buf = [0u8; Self::len()];
762 buf.clone_from_slice(other);
763 Some(Self::new_from_array(buf))
764 }
765 #[doc = "Copy from contents from another slice, padding with zeros or truncating when needed"]
766 pub fn new_from_zeroed(other: &[u8]) -> Self {
767 let mut buf = [0u8; Self::len()];
768 let len = buf.len().min(other.len());
769 buf[..len].clone_from_slice(&other[..len]);
770 Self::new_from_array(buf)
771 }
772 pub fn new_from_array(buf: [u8; 4usize]) -> Self {
773 unsafe { std::mem::transmute(buf) }
774 }
775 pub fn as_slice(&self) -> &[u8] {
776 unsafe {
777 let ptr: *const u8 = std::mem::transmute(self as *const Self);
778 std::slice::from_raw_parts(ptr, Self::len())
779 }
780 }
781 pub fn from_slice(buf: &[u8]) -> &Self {
782 assert!(buf.len() >= Self::len());
783 assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
784 unsafe { std::mem::transmute(buf.as_ptr()) }
785 }
786 pub fn as_array(&self) -> &[u8; 4usize] {
787 unsafe { std::mem::transmute(self) }
788 }
789 pub fn from_array(buf: &[u8; 4usize]) -> &Self {
790 assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
791 unsafe { std::mem::transmute(buf) }
792 }
793 pub fn into_array(self) -> [u8; 4usize] {
794 unsafe { std::mem::transmute(self) }
795 }
796 pub const fn len() -> usize {
797 const _: () = assert!(std::mem::size_of::<OvsKeyUdp>() == 4usize);
798 4usize
799 }
800 pub fn udp_src(&self) -> u16 {
801 u16::from_be(self._udp_src_be)
802 }
803 pub fn set_udp_src(&mut self, value: u16) {
804 self._udp_src_be = value.to_be();
805 }
806 pub fn udp_dst(&self) -> u16 {
807 u16::from_be(self._udp_dst_be)
808 }
809 pub fn set_udp_dst(&mut self, value: u16) {
810 self._udp_dst_be = value.to_be();
811 }
812}
813impl std::fmt::Debug for OvsKeyUdp {
814 fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
815 fmt.debug_struct("OvsKeyUdp")
816 .field("udp_src", &self.udp_src())
817 .field("udp_dst", &self.udp_dst())
818 .finish()
819 }
820}
821#[repr(C, packed(4))]
822pub struct OvsKeySctp {
823 pub _sctp_src_be: u16,
824 pub _sctp_dst_be: u16,
825}
826impl Clone for OvsKeySctp {
827 fn clone(&self) -> Self {
828 Self::new_from_array(*self.as_array())
829 }
830}
831#[doc = "Create zero-initialized struct"]
832impl Default for OvsKeySctp {
833 fn default() -> Self {
834 Self::new()
835 }
836}
837impl OvsKeySctp {
838 #[doc = "Create zero-initialized struct"]
839 pub fn new() -> Self {
840 Self::new_from_array([0u8; Self::len()])
841 }
842 #[doc = "Copy from contents from slice"]
843 pub fn new_from_slice(other: &[u8]) -> Option<Self> {
844 if other.len() != Self::len() {
845 return None;
846 }
847 let mut buf = [0u8; Self::len()];
848 buf.clone_from_slice(other);
849 Some(Self::new_from_array(buf))
850 }
851 #[doc = "Copy from contents from another slice, padding with zeros or truncating when needed"]
852 pub fn new_from_zeroed(other: &[u8]) -> Self {
853 let mut buf = [0u8; Self::len()];
854 let len = buf.len().min(other.len());
855 buf[..len].clone_from_slice(&other[..len]);
856 Self::new_from_array(buf)
857 }
858 pub fn new_from_array(buf: [u8; 4usize]) -> Self {
859 unsafe { std::mem::transmute(buf) }
860 }
861 pub fn as_slice(&self) -> &[u8] {
862 unsafe {
863 let ptr: *const u8 = std::mem::transmute(self as *const Self);
864 std::slice::from_raw_parts(ptr, Self::len())
865 }
866 }
867 pub fn from_slice(buf: &[u8]) -> &Self {
868 assert!(buf.len() >= Self::len());
869 assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
870 unsafe { std::mem::transmute(buf.as_ptr()) }
871 }
872 pub fn as_array(&self) -> &[u8; 4usize] {
873 unsafe { std::mem::transmute(self) }
874 }
875 pub fn from_array(buf: &[u8; 4usize]) -> &Self {
876 assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
877 unsafe { std::mem::transmute(buf) }
878 }
879 pub fn into_array(self) -> [u8; 4usize] {
880 unsafe { std::mem::transmute(self) }
881 }
882 pub const fn len() -> usize {
883 const _: () = assert!(std::mem::size_of::<OvsKeySctp>() == 4usize);
884 4usize
885 }
886 pub fn sctp_src(&self) -> u16 {
887 u16::from_be(self._sctp_src_be)
888 }
889 pub fn set_sctp_src(&mut self, value: u16) {
890 self._sctp_src_be = value.to_be();
891 }
892 pub fn sctp_dst(&self) -> u16 {
893 u16::from_be(self._sctp_dst_be)
894 }
895 pub fn set_sctp_dst(&mut self, value: u16) {
896 self._sctp_dst_be = value.to_be();
897 }
898}
899impl std::fmt::Debug for OvsKeySctp {
900 fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
901 fmt.debug_struct("OvsKeySctp")
902 .field("sctp_src", &self.sctp_src())
903 .field("sctp_dst", &self.sctp_dst())
904 .finish()
905 }
906}
907#[derive(Debug)]
908#[repr(C, packed(4))]
909pub struct OvsKeyIcmp {
910 pub icmp_type: u8,
911 pub icmp_code: u8,
912}
913impl Clone for OvsKeyIcmp {
914 fn clone(&self) -> Self {
915 Self::new_from_array(*self.as_array())
916 }
917}
918#[doc = "Create zero-initialized struct"]
919impl Default for OvsKeyIcmp {
920 fn default() -> Self {
921 Self::new()
922 }
923}
924impl OvsKeyIcmp {
925 #[doc = "Create zero-initialized struct"]
926 pub fn new() -> Self {
927 Self::new_from_array([0u8; Self::len()])
928 }
929 #[doc = "Copy from contents from slice"]
930 pub fn new_from_slice(other: &[u8]) -> Option<Self> {
931 if other.len() != Self::len() {
932 return None;
933 }
934 let mut buf = [0u8; Self::len()];
935 buf.clone_from_slice(other);
936 Some(Self::new_from_array(buf))
937 }
938 #[doc = "Copy from contents from another slice, padding with zeros or truncating when needed"]
939 pub fn new_from_zeroed(other: &[u8]) -> Self {
940 let mut buf = [0u8; Self::len()];
941 let len = buf.len().min(other.len());
942 buf[..len].clone_from_slice(&other[..len]);
943 Self::new_from_array(buf)
944 }
945 pub fn new_from_array(buf: [u8; 2usize]) -> Self {
946 unsafe { std::mem::transmute(buf) }
947 }
948 pub fn as_slice(&self) -> &[u8] {
949 unsafe {
950 let ptr: *const u8 = std::mem::transmute(self as *const Self);
951 std::slice::from_raw_parts(ptr, Self::len())
952 }
953 }
954 pub fn from_slice(buf: &[u8]) -> &Self {
955 assert!(buf.len() >= Self::len());
956 assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
957 unsafe { std::mem::transmute(buf.as_ptr()) }
958 }
959 pub fn as_array(&self) -> &[u8; 2usize] {
960 unsafe { std::mem::transmute(self) }
961 }
962 pub fn from_array(buf: &[u8; 2usize]) -> &Self {
963 assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
964 unsafe { std::mem::transmute(buf) }
965 }
966 pub fn into_array(self) -> [u8; 2usize] {
967 unsafe { std::mem::transmute(self) }
968 }
969 pub const fn len() -> usize {
970 const _: () = assert!(std::mem::size_of::<OvsKeyIcmp>() == 2usize);
971 2usize
972 }
973}
974#[repr(C, packed(4))]
975pub struct OvsKeyArp {
976 pub _arp_sip_be: u32,
977 pub _arp_tip_be: u32,
978 pub _arp_op_be: u16,
979 pub arp_sha: [u8; 6usize],
980 pub arp_tha: [u8; 6usize],
981 pub _pad_22: [u8; 2usize],
982}
983impl Clone for OvsKeyArp {
984 fn clone(&self) -> Self {
985 Self::new_from_array(*self.as_array())
986 }
987}
988#[doc = "Create zero-initialized struct"]
989impl Default for OvsKeyArp {
990 fn default() -> Self {
991 Self::new()
992 }
993}
994impl OvsKeyArp {
995 #[doc = "Create zero-initialized struct"]
996 pub fn new() -> Self {
997 Self::new_from_array([0u8; Self::len()])
998 }
999 #[doc = "Copy from contents from slice"]
1000 pub fn new_from_slice(other: &[u8]) -> Option<Self> {
1001 if other.len() != Self::len() {
1002 return None;
1003 }
1004 let mut buf = [0u8; Self::len()];
1005 buf.clone_from_slice(other);
1006 Some(Self::new_from_array(buf))
1007 }
1008 #[doc = "Copy from contents from another slice, padding with zeros or truncating when needed"]
1009 pub fn new_from_zeroed(other: &[u8]) -> Self {
1010 let mut buf = [0u8; Self::len()];
1011 let len = buf.len().min(other.len());
1012 buf[..len].clone_from_slice(&other[..len]);
1013 Self::new_from_array(buf)
1014 }
1015 pub fn new_from_array(buf: [u8; 24usize]) -> Self {
1016 unsafe { std::mem::transmute(buf) }
1017 }
1018 pub fn as_slice(&self) -> &[u8] {
1019 unsafe {
1020 let ptr: *const u8 = std::mem::transmute(self as *const Self);
1021 std::slice::from_raw_parts(ptr, Self::len())
1022 }
1023 }
1024 pub fn from_slice(buf: &[u8]) -> &Self {
1025 assert!(buf.len() >= Self::len());
1026 assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
1027 unsafe { std::mem::transmute(buf.as_ptr()) }
1028 }
1029 pub fn as_array(&self) -> &[u8; 24usize] {
1030 unsafe { std::mem::transmute(self) }
1031 }
1032 pub fn from_array(buf: &[u8; 24usize]) -> &Self {
1033 assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
1034 unsafe { std::mem::transmute(buf) }
1035 }
1036 pub fn into_array(self) -> [u8; 24usize] {
1037 unsafe { std::mem::transmute(self) }
1038 }
1039 pub const fn len() -> usize {
1040 const _: () = assert!(std::mem::size_of::<OvsKeyArp>() == 24usize);
1041 24usize
1042 }
1043 pub fn arp_sip(&self) -> u32 {
1044 u32::from_be(self._arp_sip_be)
1045 }
1046 pub fn set_arp_sip(&mut self, value: u32) {
1047 self._arp_sip_be = value.to_be();
1048 }
1049 pub fn arp_tip(&self) -> u32 {
1050 u32::from_be(self._arp_tip_be)
1051 }
1052 pub fn set_arp_tip(&mut self, value: u32) {
1053 self._arp_tip_be = value.to_be();
1054 }
1055 pub fn arp_op(&self) -> u16 {
1056 u16::from_be(self._arp_op_be)
1057 }
1058 pub fn set_arp_op(&mut self, value: u16) {
1059 self._arp_op_be = value.to_be();
1060 }
1061}
1062impl std::fmt::Debug for OvsKeyArp {
1063 fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1064 fmt.debug_struct("OvsKeyArp")
1065 .field("arp_sip", &self.arp_sip())
1066 .field("arp_tip", &self.arp_tip())
1067 .field("arp_op", &self.arp_op())
1068 .field("arp_sha", &self.arp_sha)
1069 .field("arp_tha", &self.arp_tha)
1070 .finish()
1071 }
1072}
1073#[derive(Debug)]
1074#[repr(C, packed(4))]
1075pub struct OvsKeyNd {
1076 pub nd_target: [u8; 16usize],
1077 pub nd_sll: [u8; 6usize],
1078 pub nd_tll: [u8; 6usize],
1079}
1080impl Clone for OvsKeyNd {
1081 fn clone(&self) -> Self {
1082 Self::new_from_array(*self.as_array())
1083 }
1084}
1085#[doc = "Create zero-initialized struct"]
1086impl Default for OvsKeyNd {
1087 fn default() -> Self {
1088 Self::new()
1089 }
1090}
1091impl OvsKeyNd {
1092 #[doc = "Create zero-initialized struct"]
1093 pub fn new() -> Self {
1094 Self::new_from_array([0u8; Self::len()])
1095 }
1096 #[doc = "Copy from contents from slice"]
1097 pub fn new_from_slice(other: &[u8]) -> Option<Self> {
1098 if other.len() != Self::len() {
1099 return None;
1100 }
1101 let mut buf = [0u8; Self::len()];
1102 buf.clone_from_slice(other);
1103 Some(Self::new_from_array(buf))
1104 }
1105 #[doc = "Copy from contents from another slice, padding with zeros or truncating when needed"]
1106 pub fn new_from_zeroed(other: &[u8]) -> Self {
1107 let mut buf = [0u8; Self::len()];
1108 let len = buf.len().min(other.len());
1109 buf[..len].clone_from_slice(&other[..len]);
1110 Self::new_from_array(buf)
1111 }
1112 pub fn new_from_array(buf: [u8; 28usize]) -> Self {
1113 unsafe { std::mem::transmute(buf) }
1114 }
1115 pub fn as_slice(&self) -> &[u8] {
1116 unsafe {
1117 let ptr: *const u8 = std::mem::transmute(self as *const Self);
1118 std::slice::from_raw_parts(ptr, Self::len())
1119 }
1120 }
1121 pub fn from_slice(buf: &[u8]) -> &Self {
1122 assert!(buf.len() >= Self::len());
1123 assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
1124 unsafe { std::mem::transmute(buf.as_ptr()) }
1125 }
1126 pub fn as_array(&self) -> &[u8; 28usize] {
1127 unsafe { std::mem::transmute(self) }
1128 }
1129 pub fn from_array(buf: &[u8; 28usize]) -> &Self {
1130 assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
1131 unsafe { std::mem::transmute(buf) }
1132 }
1133 pub fn into_array(self) -> [u8; 28usize] {
1134 unsafe { std::mem::transmute(self) }
1135 }
1136 pub const fn len() -> usize {
1137 const _: () = assert!(std::mem::size_of::<OvsKeyNd>() == 28usize);
1138 28usize
1139 }
1140}
1141#[repr(C, packed(4))]
1142pub struct OvsKeyCtTupleIpv4 {
1143 pub _ipv4_src_be: u32,
1144 pub _ipv4_dst_be: u32,
1145 pub _src_port_be: u16,
1146 pub _dst_port_be: u16,
1147 pub ipv4_proto: u8,
1148 pub _pad_13: [u8; 3usize],
1149}
1150impl Clone for OvsKeyCtTupleIpv4 {
1151 fn clone(&self) -> Self {
1152 Self::new_from_array(*self.as_array())
1153 }
1154}
1155#[doc = "Create zero-initialized struct"]
1156impl Default for OvsKeyCtTupleIpv4 {
1157 fn default() -> Self {
1158 Self::new()
1159 }
1160}
1161impl OvsKeyCtTupleIpv4 {
1162 #[doc = "Create zero-initialized struct"]
1163 pub fn new() -> Self {
1164 Self::new_from_array([0u8; Self::len()])
1165 }
1166 #[doc = "Copy from contents from slice"]
1167 pub fn new_from_slice(other: &[u8]) -> Option<Self> {
1168 if other.len() != Self::len() {
1169 return None;
1170 }
1171 let mut buf = [0u8; Self::len()];
1172 buf.clone_from_slice(other);
1173 Some(Self::new_from_array(buf))
1174 }
1175 #[doc = "Copy from contents from another slice, padding with zeros or truncating when needed"]
1176 pub fn new_from_zeroed(other: &[u8]) -> Self {
1177 let mut buf = [0u8; Self::len()];
1178 let len = buf.len().min(other.len());
1179 buf[..len].clone_from_slice(&other[..len]);
1180 Self::new_from_array(buf)
1181 }
1182 pub fn new_from_array(buf: [u8; 16usize]) -> Self {
1183 unsafe { std::mem::transmute(buf) }
1184 }
1185 pub fn as_slice(&self) -> &[u8] {
1186 unsafe {
1187 let ptr: *const u8 = std::mem::transmute(self as *const Self);
1188 std::slice::from_raw_parts(ptr, Self::len())
1189 }
1190 }
1191 pub fn from_slice(buf: &[u8]) -> &Self {
1192 assert!(buf.len() >= Self::len());
1193 assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
1194 unsafe { std::mem::transmute(buf.as_ptr()) }
1195 }
1196 pub fn as_array(&self) -> &[u8; 16usize] {
1197 unsafe { std::mem::transmute(self) }
1198 }
1199 pub fn from_array(buf: &[u8; 16usize]) -> &Self {
1200 assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
1201 unsafe { std::mem::transmute(buf) }
1202 }
1203 pub fn into_array(self) -> [u8; 16usize] {
1204 unsafe { std::mem::transmute(self) }
1205 }
1206 pub const fn len() -> usize {
1207 const _: () = assert!(std::mem::size_of::<OvsKeyCtTupleIpv4>() == 16usize);
1208 16usize
1209 }
1210 pub fn ipv4_src(&self) -> u32 {
1211 u32::from_be(self._ipv4_src_be)
1212 }
1213 pub fn set_ipv4_src(&mut self, value: u32) {
1214 self._ipv4_src_be = value.to_be();
1215 }
1216 pub fn ipv4_dst(&self) -> u32 {
1217 u32::from_be(self._ipv4_dst_be)
1218 }
1219 pub fn set_ipv4_dst(&mut self, value: u32) {
1220 self._ipv4_dst_be = value.to_be();
1221 }
1222 pub fn src_port(&self) -> u16 {
1223 u16::from_be(self._src_port_be)
1224 }
1225 pub fn set_src_port(&mut self, value: u16) {
1226 self._src_port_be = value.to_be();
1227 }
1228 pub fn dst_port(&self) -> u16 {
1229 u16::from_be(self._dst_port_be)
1230 }
1231 pub fn set_dst_port(&mut self, value: u16) {
1232 self._dst_port_be = value.to_be();
1233 }
1234}
1235impl std::fmt::Debug for OvsKeyCtTupleIpv4 {
1236 fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1237 fmt.debug_struct("OvsKeyCtTupleIpv4")
1238 .field("ipv4_src", &self.ipv4_src())
1239 .field("ipv4_dst", &self.ipv4_dst())
1240 .field("src_port", &self.src_port())
1241 .field("dst_port", &self.dst_port())
1242 .field("ipv4_proto", &self.ipv4_proto)
1243 .finish()
1244 }
1245}
1246#[repr(C, packed(4))]
1247pub struct OvsActionPushVlan {
1248 #[doc = "Tag protocol identifier (TPID) to push.\n"]
1249 pub _vlan_tpid_be: u16,
1250 #[doc = "Tag control identifier (TCI) to push.\n"]
1251 pub _vlan_tci_be: u16,
1252}
1253impl Clone for OvsActionPushVlan {
1254 fn clone(&self) -> Self {
1255 Self::new_from_array(*self.as_array())
1256 }
1257}
1258#[doc = "Create zero-initialized struct"]
1259impl Default for OvsActionPushVlan {
1260 fn default() -> Self {
1261 Self::new()
1262 }
1263}
1264impl OvsActionPushVlan {
1265 #[doc = "Create zero-initialized struct"]
1266 pub fn new() -> Self {
1267 Self::new_from_array([0u8; Self::len()])
1268 }
1269 #[doc = "Copy from contents from slice"]
1270 pub fn new_from_slice(other: &[u8]) -> Option<Self> {
1271 if other.len() != Self::len() {
1272 return None;
1273 }
1274 let mut buf = [0u8; Self::len()];
1275 buf.clone_from_slice(other);
1276 Some(Self::new_from_array(buf))
1277 }
1278 #[doc = "Copy from contents from another slice, padding with zeros or truncating when needed"]
1279 pub fn new_from_zeroed(other: &[u8]) -> Self {
1280 let mut buf = [0u8; Self::len()];
1281 let len = buf.len().min(other.len());
1282 buf[..len].clone_from_slice(&other[..len]);
1283 Self::new_from_array(buf)
1284 }
1285 pub fn new_from_array(buf: [u8; 4usize]) -> Self {
1286 unsafe { std::mem::transmute(buf) }
1287 }
1288 pub fn as_slice(&self) -> &[u8] {
1289 unsafe {
1290 let ptr: *const u8 = std::mem::transmute(self as *const Self);
1291 std::slice::from_raw_parts(ptr, Self::len())
1292 }
1293 }
1294 pub fn from_slice(buf: &[u8]) -> &Self {
1295 assert!(buf.len() >= Self::len());
1296 assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
1297 unsafe { std::mem::transmute(buf.as_ptr()) }
1298 }
1299 pub fn as_array(&self) -> &[u8; 4usize] {
1300 unsafe { std::mem::transmute(self) }
1301 }
1302 pub fn from_array(buf: &[u8; 4usize]) -> &Self {
1303 assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
1304 unsafe { std::mem::transmute(buf) }
1305 }
1306 pub fn into_array(self) -> [u8; 4usize] {
1307 unsafe { std::mem::transmute(self) }
1308 }
1309 pub const fn len() -> usize {
1310 const _: () = assert!(std::mem::size_of::<OvsActionPushVlan>() == 4usize);
1311 4usize
1312 }
1313 #[doc = "Tag protocol identifier (TPID) to push.\n"]
1314 pub fn vlan_tpid(&self) -> u16 {
1315 u16::from_be(self._vlan_tpid_be)
1316 }
1317 #[doc = "Tag protocol identifier (TPID) to push.\n"]
1318 pub fn set_vlan_tpid(&mut self, value: u16) {
1319 self._vlan_tpid_be = value.to_be();
1320 }
1321 #[doc = "Tag control identifier (TCI) to push.\n"]
1322 pub fn vlan_tci(&self) -> u16 {
1323 u16::from_be(self._vlan_tci_be)
1324 }
1325 #[doc = "Tag control identifier (TCI) to push.\n"]
1326 pub fn set_vlan_tci(&mut self, value: u16) {
1327 self._vlan_tci_be = value.to_be();
1328 }
1329}
1330impl std::fmt::Debug for OvsActionPushVlan {
1331 fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1332 fmt.debug_struct("OvsActionPushVlan")
1333 .field("vlan_tpid", &self.vlan_tpid())
1334 .field("vlan_tci", &self.vlan_tci())
1335 .finish()
1336 }
1337}
1338#[derive(Debug)]
1339#[repr(C, packed(4))]
1340pub struct OvsActionHash {
1341 #[doc = "Algorithm used to compute hash prior to recirculation.\n"]
1342 pub hash_alg: u32,
1343 #[doc = "Basis used for computing hash.\n"]
1344 pub hash_basis: u32,
1345}
1346impl Clone for OvsActionHash {
1347 fn clone(&self) -> Self {
1348 Self::new_from_array(*self.as_array())
1349 }
1350}
1351#[doc = "Create zero-initialized struct"]
1352impl Default for OvsActionHash {
1353 fn default() -> Self {
1354 Self::new()
1355 }
1356}
1357impl OvsActionHash {
1358 #[doc = "Create zero-initialized struct"]
1359 pub fn new() -> Self {
1360 Self::new_from_array([0u8; Self::len()])
1361 }
1362 #[doc = "Copy from contents from slice"]
1363 pub fn new_from_slice(other: &[u8]) -> Option<Self> {
1364 if other.len() != Self::len() {
1365 return None;
1366 }
1367 let mut buf = [0u8; Self::len()];
1368 buf.clone_from_slice(other);
1369 Some(Self::new_from_array(buf))
1370 }
1371 #[doc = "Copy from contents from another slice, padding with zeros or truncating when needed"]
1372 pub fn new_from_zeroed(other: &[u8]) -> Self {
1373 let mut buf = [0u8; Self::len()];
1374 let len = buf.len().min(other.len());
1375 buf[..len].clone_from_slice(&other[..len]);
1376 Self::new_from_array(buf)
1377 }
1378 pub fn new_from_array(buf: [u8; 8usize]) -> Self {
1379 unsafe { std::mem::transmute(buf) }
1380 }
1381 pub fn as_slice(&self) -> &[u8] {
1382 unsafe {
1383 let ptr: *const u8 = std::mem::transmute(self as *const Self);
1384 std::slice::from_raw_parts(ptr, Self::len())
1385 }
1386 }
1387 pub fn from_slice(buf: &[u8]) -> &Self {
1388 assert!(buf.len() >= Self::len());
1389 assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
1390 unsafe { std::mem::transmute(buf.as_ptr()) }
1391 }
1392 pub fn as_array(&self) -> &[u8; 8usize] {
1393 unsafe { std::mem::transmute(self) }
1394 }
1395 pub fn from_array(buf: &[u8; 8usize]) -> &Self {
1396 assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
1397 unsafe { std::mem::transmute(buf) }
1398 }
1399 pub fn into_array(self) -> [u8; 8usize] {
1400 unsafe { std::mem::transmute(self) }
1401 }
1402 pub const fn len() -> usize {
1403 const _: () = assert!(std::mem::size_of::<OvsActionHash>() == 8usize);
1404 8usize
1405 }
1406}
1407#[repr(C, packed(4))]
1408pub struct OvsActionPushMpls {
1409 #[doc = "MPLS label stack entry to push\n"]
1410 pub _mpls_lse_be: u32,
1411 #[doc = "Ethertype to set in the encapsulating ethernet frame. The only values\nethertype should ever be given are ETH_P_MPLS_UC and ETH_P_MPLS_MC,\nindicating MPLS unicast or multicast. Other are rejected.\n"]
1412 pub _mpls_ethertype_be: u32,
1413}
1414impl Clone for OvsActionPushMpls {
1415 fn clone(&self) -> Self {
1416 Self::new_from_array(*self.as_array())
1417 }
1418}
1419#[doc = "Create zero-initialized struct"]
1420impl Default for OvsActionPushMpls {
1421 fn default() -> Self {
1422 Self::new()
1423 }
1424}
1425impl OvsActionPushMpls {
1426 #[doc = "Create zero-initialized struct"]
1427 pub fn new() -> Self {
1428 Self::new_from_array([0u8; Self::len()])
1429 }
1430 #[doc = "Copy from contents from slice"]
1431 pub fn new_from_slice(other: &[u8]) -> Option<Self> {
1432 if other.len() != Self::len() {
1433 return None;
1434 }
1435 let mut buf = [0u8; Self::len()];
1436 buf.clone_from_slice(other);
1437 Some(Self::new_from_array(buf))
1438 }
1439 #[doc = "Copy from contents from another slice, padding with zeros or truncating when needed"]
1440 pub fn new_from_zeroed(other: &[u8]) -> Self {
1441 let mut buf = [0u8; Self::len()];
1442 let len = buf.len().min(other.len());
1443 buf[..len].clone_from_slice(&other[..len]);
1444 Self::new_from_array(buf)
1445 }
1446 pub fn new_from_array(buf: [u8; 8usize]) -> Self {
1447 unsafe { std::mem::transmute(buf) }
1448 }
1449 pub fn as_slice(&self) -> &[u8] {
1450 unsafe {
1451 let ptr: *const u8 = std::mem::transmute(self as *const Self);
1452 std::slice::from_raw_parts(ptr, Self::len())
1453 }
1454 }
1455 pub fn from_slice(buf: &[u8]) -> &Self {
1456 assert!(buf.len() >= Self::len());
1457 assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
1458 unsafe { std::mem::transmute(buf.as_ptr()) }
1459 }
1460 pub fn as_array(&self) -> &[u8; 8usize] {
1461 unsafe { std::mem::transmute(self) }
1462 }
1463 pub fn from_array(buf: &[u8; 8usize]) -> &Self {
1464 assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
1465 unsafe { std::mem::transmute(buf) }
1466 }
1467 pub fn into_array(self) -> [u8; 8usize] {
1468 unsafe { std::mem::transmute(self) }
1469 }
1470 pub const fn len() -> usize {
1471 const _: () = assert!(std::mem::size_of::<OvsActionPushMpls>() == 8usize);
1472 8usize
1473 }
1474 #[doc = "MPLS label stack entry to push\n"]
1475 pub fn mpls_lse(&self) -> u32 {
1476 u32::from_be(self._mpls_lse_be)
1477 }
1478 #[doc = "MPLS label stack entry to push\n"]
1479 pub fn set_mpls_lse(&mut self, value: u32) {
1480 self._mpls_lse_be = value.to_be();
1481 }
1482 #[doc = "Ethertype to set in the encapsulating ethernet frame. The only values\nethertype should ever be given are ETH_P_MPLS_UC and ETH_P_MPLS_MC,\nindicating MPLS unicast or multicast. Other are rejected.\n"]
1483 pub fn mpls_ethertype(&self) -> u32 {
1484 u32::from_be(self._mpls_ethertype_be)
1485 }
1486 #[doc = "Ethertype to set in the encapsulating ethernet frame. The only values\nethertype should ever be given are ETH_P_MPLS_UC and ETH_P_MPLS_MC,\nindicating MPLS unicast or multicast. Other are rejected.\n"]
1487 pub fn set_mpls_ethertype(&mut self, value: u32) {
1488 self._mpls_ethertype_be = value.to_be();
1489 }
1490}
1491impl std::fmt::Debug for OvsActionPushMpls {
1492 fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1493 fmt.debug_struct("OvsActionPushMpls")
1494 .field("mpls_lse", &self.mpls_lse())
1495 .field("mpls_ethertype", &self.mpls_ethertype())
1496 .finish()
1497 }
1498}
1499#[repr(C, packed(4))]
1500pub struct OvsActionAddMpls {
1501 #[doc = "MPLS label stack entry to push\n"]
1502 pub _mpls_lse_be: u32,
1503 #[doc = "Ethertype to set in the encapsulating ethernet frame. The only values\nethertype should ever be given are ETH_P_MPLS_UC and ETH_P_MPLS_MC,\nindicating MPLS unicast or multicast. Other are rejected.\n"]
1504 pub _mpls_ethertype_be: u32,
1505 #[doc = "MPLS tunnel attributes.\n"]
1506 pub tun_flags: u16,
1507 pub _pad_10: [u8; 2usize],
1508}
1509impl Clone for OvsActionAddMpls {
1510 fn clone(&self) -> Self {
1511 Self::new_from_array(*self.as_array())
1512 }
1513}
1514#[doc = "Create zero-initialized struct"]
1515impl Default for OvsActionAddMpls {
1516 fn default() -> Self {
1517 Self::new()
1518 }
1519}
1520impl OvsActionAddMpls {
1521 #[doc = "Create zero-initialized struct"]
1522 pub fn new() -> Self {
1523 Self::new_from_array([0u8; Self::len()])
1524 }
1525 #[doc = "Copy from contents from slice"]
1526 pub fn new_from_slice(other: &[u8]) -> Option<Self> {
1527 if other.len() != Self::len() {
1528 return None;
1529 }
1530 let mut buf = [0u8; Self::len()];
1531 buf.clone_from_slice(other);
1532 Some(Self::new_from_array(buf))
1533 }
1534 #[doc = "Copy from contents from another slice, padding with zeros or truncating when needed"]
1535 pub fn new_from_zeroed(other: &[u8]) -> Self {
1536 let mut buf = [0u8; Self::len()];
1537 let len = buf.len().min(other.len());
1538 buf[..len].clone_from_slice(&other[..len]);
1539 Self::new_from_array(buf)
1540 }
1541 pub fn new_from_array(buf: [u8; 12usize]) -> Self {
1542 unsafe { std::mem::transmute(buf) }
1543 }
1544 pub fn as_slice(&self) -> &[u8] {
1545 unsafe {
1546 let ptr: *const u8 = std::mem::transmute(self as *const Self);
1547 std::slice::from_raw_parts(ptr, Self::len())
1548 }
1549 }
1550 pub fn from_slice(buf: &[u8]) -> &Self {
1551 assert!(buf.len() >= Self::len());
1552 assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
1553 unsafe { std::mem::transmute(buf.as_ptr()) }
1554 }
1555 pub fn as_array(&self) -> &[u8; 12usize] {
1556 unsafe { std::mem::transmute(self) }
1557 }
1558 pub fn from_array(buf: &[u8; 12usize]) -> &Self {
1559 assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
1560 unsafe { std::mem::transmute(buf) }
1561 }
1562 pub fn into_array(self) -> [u8; 12usize] {
1563 unsafe { std::mem::transmute(self) }
1564 }
1565 pub const fn len() -> usize {
1566 const _: () = assert!(std::mem::size_of::<OvsActionAddMpls>() == 12usize);
1567 12usize
1568 }
1569 #[doc = "MPLS label stack entry to push\n"]
1570 pub fn mpls_lse(&self) -> u32 {
1571 u32::from_be(self._mpls_lse_be)
1572 }
1573 #[doc = "MPLS label stack entry to push\n"]
1574 pub fn set_mpls_lse(&mut self, value: u32) {
1575 self._mpls_lse_be = value.to_be();
1576 }
1577 #[doc = "Ethertype to set in the encapsulating ethernet frame. The only values\nethertype should ever be given are ETH_P_MPLS_UC and ETH_P_MPLS_MC,\nindicating MPLS unicast or multicast. Other are rejected.\n"]
1578 pub fn mpls_ethertype(&self) -> u32 {
1579 u32::from_be(self._mpls_ethertype_be)
1580 }
1581 #[doc = "Ethertype to set in the encapsulating ethernet frame. The only values\nethertype should ever be given are ETH_P_MPLS_UC and ETH_P_MPLS_MC,\nindicating MPLS unicast or multicast. Other are rejected.\n"]
1582 pub fn set_mpls_ethertype(&mut self, value: u32) {
1583 self._mpls_ethertype_be = value.to_be();
1584 }
1585}
1586impl std::fmt::Debug for OvsActionAddMpls {
1587 fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1588 fmt.debug_struct("OvsActionAddMpls")
1589 .field("mpls_lse", &self.mpls_lse())
1590 .field("mpls_ethertype", &self.mpls_ethertype())
1591 .field("tun_flags", &self.tun_flags)
1592 .finish()
1593 }
1594}
1595#[derive(Clone)]
1596pub enum FlowAttrs<'a> {
1597 #[doc = "Nested attributes specifying the flow key. Always present in\nnotifications. Required for all requests (except dumps).\n"]
1598 Key(IterableKeyAttrs<'a>),
1599 #[doc = "Nested attributes specifying the actions to take for packets that match\nthe key. Always present in notifications. Required for OVS_FLOW_CMD_NEW\nrequests, optional for OVS_FLOW_CMD_SET requests. An OVS_FLOW_CMD_SET\nwithout OVS_FLOW_ATTR_ACTIONS will not modify the actions. To clear the\nactions, an OVS_FLOW_ATTR_ACTIONS without any nested attributes must be\ngiven.\n"]
1600 Actions(IterableActionAttrs<'a>),
1601 #[doc = "Statistics for this flow. Present in notifications if the stats would be\nnonzero. Ignored in requests.\n"]
1602 Stats(OvsFlowStats),
1603 #[doc = "An 8-bit value giving the ORed value of all of the TCP flags seen on\npackets in this flow. Only present in notifications for TCP flows, and\nonly if it would be nonzero. Ignored in requests.\n"]
1604 TcpFlags(u8),
1605 #[doc = "A 64-bit integer giving the time, in milliseconds on the system\nmonotonic clock, at which a packet was last processed for this flow.\nOnly present in notifications if a packet has been processed for this\nflow. Ignored in requests.\n"]
1606 Used(u64),
1607 #[doc = "If present in a OVS_FLOW_CMD_SET request, clears the last-used time,\naccumulated TCP flags, and statistics for this flow. Otherwise ignored\nin requests. Never present in notifications.\n"]
1608 Clear(()),
1609 #[doc = "Nested attributes specifying the mask bits for wildcarded flow match.\nMask bit value \\'1\\' specifies exact match with corresponding flow key\nbit, while mask bit value \\'0\\' specifies a wildcarded match. Omitting\nattribute is treated as wildcarding all corresponding fields. Optional\nfor all requests. If not present, all flow key bits are exact match\nbits.\n"]
1610 Mask(IterableKeyAttrs<'a>),
1611 #[doc = "Flow operation is a feature probe, error logging should be suppressed.\n"]
1612 Probe(&'a [u8]),
1613 #[doc = "A value between 1-16 octets specifying a unique identifier for the flow.\nCauses the flow to be indexed by this value rather than the value of the\nOVS_FLOW_ATTR_KEY attribute. Optional for all requests. Present in\nnotifications if the flow was created with this attribute.\n"]
1614 Ufid(&'a [u8]),
1615 #[doc = "A 32-bit value of ORed flags that provide alternative semantics for flow\ninstallation and retrieval. Optional for all requests.\n\nAssociated type: [`OvsUfidFlags`] (enum)"]
1616 UfidFlags(u32),
1617 Pad(&'a [u8]),
1618}
1619impl<'a> IterableFlowAttrs<'a> {
1620 #[doc = "Nested attributes specifying the flow key. Always present in\nnotifications. Required for all requests (except dumps).\n"]
1621 pub fn get_key(&self) -> Result<IterableKeyAttrs<'a>, ErrorContext> {
1622 let mut iter = self.clone();
1623 iter.pos = 0;
1624 for attr in iter {
1625 if let Ok(FlowAttrs::Key(val)) = attr {
1626 return Ok(val);
1627 }
1628 }
1629 Err(ErrorContext::new_missing(
1630 "FlowAttrs",
1631 "Key",
1632 self.orig_loc,
1633 self.buf.as_ptr() as usize,
1634 ))
1635 }
1636 #[doc = "Nested attributes specifying the actions to take for packets that match\nthe key. Always present in notifications. Required for OVS_FLOW_CMD_NEW\nrequests, optional for OVS_FLOW_CMD_SET requests. An OVS_FLOW_CMD_SET\nwithout OVS_FLOW_ATTR_ACTIONS will not modify the actions. To clear the\nactions, an OVS_FLOW_ATTR_ACTIONS without any nested attributes must be\ngiven.\n"]
1637 pub fn get_actions(&self) -> Result<IterableActionAttrs<'a>, ErrorContext> {
1638 let mut iter = self.clone();
1639 iter.pos = 0;
1640 for attr in iter {
1641 if let Ok(FlowAttrs::Actions(val)) = attr {
1642 return Ok(val);
1643 }
1644 }
1645 Err(ErrorContext::new_missing(
1646 "FlowAttrs",
1647 "Actions",
1648 self.orig_loc,
1649 self.buf.as_ptr() as usize,
1650 ))
1651 }
1652 #[doc = "Statistics for this flow. Present in notifications if the stats would be\nnonzero. Ignored in requests.\n"]
1653 pub fn get_stats(&self) -> Result<OvsFlowStats, ErrorContext> {
1654 let mut iter = self.clone();
1655 iter.pos = 0;
1656 for attr in iter {
1657 if let Ok(FlowAttrs::Stats(val)) = attr {
1658 return Ok(val);
1659 }
1660 }
1661 Err(ErrorContext::new_missing(
1662 "FlowAttrs",
1663 "Stats",
1664 self.orig_loc,
1665 self.buf.as_ptr() as usize,
1666 ))
1667 }
1668 #[doc = "An 8-bit value giving the ORed value of all of the TCP flags seen on\npackets in this flow. Only present in notifications for TCP flows, and\nonly if it would be nonzero. Ignored in requests.\n"]
1669 pub fn get_tcp_flags(&self) -> Result<u8, ErrorContext> {
1670 let mut iter = self.clone();
1671 iter.pos = 0;
1672 for attr in iter {
1673 if let Ok(FlowAttrs::TcpFlags(val)) = attr {
1674 return Ok(val);
1675 }
1676 }
1677 Err(ErrorContext::new_missing(
1678 "FlowAttrs",
1679 "TcpFlags",
1680 self.orig_loc,
1681 self.buf.as_ptr() as usize,
1682 ))
1683 }
1684 #[doc = "A 64-bit integer giving the time, in milliseconds on the system\nmonotonic clock, at which a packet was last processed for this flow.\nOnly present in notifications if a packet has been processed for this\nflow. Ignored in requests.\n"]
1685 pub fn get_used(&self) -> Result<u64, ErrorContext> {
1686 let mut iter = self.clone();
1687 iter.pos = 0;
1688 for attr in iter {
1689 if let Ok(FlowAttrs::Used(val)) = attr {
1690 return Ok(val);
1691 }
1692 }
1693 Err(ErrorContext::new_missing(
1694 "FlowAttrs",
1695 "Used",
1696 self.orig_loc,
1697 self.buf.as_ptr() as usize,
1698 ))
1699 }
1700 #[doc = "If present in a OVS_FLOW_CMD_SET request, clears the last-used time,\naccumulated TCP flags, and statistics for this flow. Otherwise ignored\nin requests. Never present in notifications.\n"]
1701 pub fn get_clear(&self) -> Result<(), ErrorContext> {
1702 let mut iter = self.clone();
1703 iter.pos = 0;
1704 for attr in iter {
1705 if let Ok(FlowAttrs::Clear(val)) = attr {
1706 return Ok(val);
1707 }
1708 }
1709 Err(ErrorContext::new_missing(
1710 "FlowAttrs",
1711 "Clear",
1712 self.orig_loc,
1713 self.buf.as_ptr() as usize,
1714 ))
1715 }
1716 #[doc = "Nested attributes specifying the mask bits for wildcarded flow match.\nMask bit value \\'1\\' specifies exact match with corresponding flow key\nbit, while mask bit value \\'0\\' specifies a wildcarded match. Omitting\nattribute is treated as wildcarding all corresponding fields. Optional\nfor all requests. If not present, all flow key bits are exact match\nbits.\n"]
1717 pub fn get_mask(&self) -> Result<IterableKeyAttrs<'a>, ErrorContext> {
1718 let mut iter = self.clone();
1719 iter.pos = 0;
1720 for attr in iter {
1721 if let Ok(FlowAttrs::Mask(val)) = attr {
1722 return Ok(val);
1723 }
1724 }
1725 Err(ErrorContext::new_missing(
1726 "FlowAttrs",
1727 "Mask",
1728 self.orig_loc,
1729 self.buf.as_ptr() as usize,
1730 ))
1731 }
1732 #[doc = "Flow operation is a feature probe, error logging should be suppressed.\n"]
1733 pub fn get_probe(&self) -> Result<&'a [u8], ErrorContext> {
1734 let mut iter = self.clone();
1735 iter.pos = 0;
1736 for attr in iter {
1737 if let Ok(FlowAttrs::Probe(val)) = attr {
1738 return Ok(val);
1739 }
1740 }
1741 Err(ErrorContext::new_missing(
1742 "FlowAttrs",
1743 "Probe",
1744 self.orig_loc,
1745 self.buf.as_ptr() as usize,
1746 ))
1747 }
1748 #[doc = "A value between 1-16 octets specifying a unique identifier for the flow.\nCauses the flow to be indexed by this value rather than the value of the\nOVS_FLOW_ATTR_KEY attribute. Optional for all requests. Present in\nnotifications if the flow was created with this attribute.\n"]
1749 pub fn get_ufid(&self) -> Result<&'a [u8], ErrorContext> {
1750 let mut iter = self.clone();
1751 iter.pos = 0;
1752 for attr in iter {
1753 if let Ok(FlowAttrs::Ufid(val)) = attr {
1754 return Ok(val);
1755 }
1756 }
1757 Err(ErrorContext::new_missing(
1758 "FlowAttrs",
1759 "Ufid",
1760 self.orig_loc,
1761 self.buf.as_ptr() as usize,
1762 ))
1763 }
1764 #[doc = "A 32-bit value of ORed flags that provide alternative semantics for flow\ninstallation and retrieval. Optional for all requests.\n\nAssociated type: [`OvsUfidFlags`] (enum)"]
1765 pub fn get_ufid_flags(&self) -> Result<u32, ErrorContext> {
1766 let mut iter = self.clone();
1767 iter.pos = 0;
1768 for attr in iter {
1769 if let Ok(FlowAttrs::UfidFlags(val)) = attr {
1770 return Ok(val);
1771 }
1772 }
1773 Err(ErrorContext::new_missing(
1774 "FlowAttrs",
1775 "UfidFlags",
1776 self.orig_loc,
1777 self.buf.as_ptr() as usize,
1778 ))
1779 }
1780 pub fn get_pad(&self) -> Result<&'a [u8], ErrorContext> {
1781 let mut iter = self.clone();
1782 iter.pos = 0;
1783 for attr in iter {
1784 if let Ok(FlowAttrs::Pad(val)) = attr {
1785 return Ok(val);
1786 }
1787 }
1788 Err(ErrorContext::new_missing(
1789 "FlowAttrs",
1790 "Pad",
1791 self.orig_loc,
1792 self.buf.as_ptr() as usize,
1793 ))
1794 }
1795}
1796impl FlowAttrs<'_> {
1797 pub fn new<'a>(buf: &'a [u8]) -> IterableFlowAttrs<'a> {
1798 IterableFlowAttrs::with_loc(buf, buf.as_ptr() as usize)
1799 }
1800 fn attr_from_type(r#type: u16) -> Option<&'static str> {
1801 let res = match r#type {
1802 1u16 => "Key",
1803 2u16 => "Actions",
1804 3u16 => "Stats",
1805 4u16 => "TcpFlags",
1806 5u16 => "Used",
1807 6u16 => "Clear",
1808 7u16 => "Mask",
1809 8u16 => "Probe",
1810 9u16 => "Ufid",
1811 10u16 => "UfidFlags",
1812 11u16 => "Pad",
1813 _ => return None,
1814 };
1815 Some(res)
1816 }
1817}
1818#[derive(Clone, Copy, Default)]
1819pub struct IterableFlowAttrs<'a> {
1820 buf: &'a [u8],
1821 pos: usize,
1822 orig_loc: usize,
1823}
1824impl<'a> IterableFlowAttrs<'a> {
1825 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
1826 Self {
1827 buf,
1828 pos: 0,
1829 orig_loc,
1830 }
1831 }
1832 pub fn get_buf(&self) -> &'a [u8] {
1833 self.buf
1834 }
1835}
1836impl<'a> Iterator for IterableFlowAttrs<'a> {
1837 type Item = Result<FlowAttrs<'a>, ErrorContext>;
1838 fn next(&mut self) -> Option<Self::Item> {
1839 let mut pos;
1840 let mut r#type;
1841 loop {
1842 pos = self.pos;
1843 r#type = None;
1844 if self.buf.len() == self.pos {
1845 return None;
1846 }
1847 let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
1848 self.pos = self.buf.len();
1849 break;
1850 };
1851 r#type = Some(header.r#type);
1852 let res = match header.r#type {
1853 1u16 => FlowAttrs::Key({
1854 let res = Some(IterableKeyAttrs::with_loc(next, self.orig_loc));
1855 let Some(val) = res else { break };
1856 val
1857 }),
1858 2u16 => FlowAttrs::Actions({
1859 let res = Some(IterableActionAttrs::with_loc(next, self.orig_loc));
1860 let Some(val) = res else { break };
1861 val
1862 }),
1863 3u16 => FlowAttrs::Stats({
1864 let res = Some(OvsFlowStats::new_from_zeroed(next));
1865 let Some(val) = res else { break };
1866 val
1867 }),
1868 4u16 => FlowAttrs::TcpFlags({
1869 let res = parse_u8(next);
1870 let Some(val) = res else { break };
1871 val
1872 }),
1873 5u16 => FlowAttrs::Used({
1874 let res = parse_u64(next);
1875 let Some(val) = res else { break };
1876 val
1877 }),
1878 6u16 => FlowAttrs::Clear(()),
1879 7u16 => FlowAttrs::Mask({
1880 let res = Some(IterableKeyAttrs::with_loc(next, self.orig_loc));
1881 let Some(val) = res else { break };
1882 val
1883 }),
1884 8u16 => FlowAttrs::Probe({
1885 let res = Some(next);
1886 let Some(val) = res else { break };
1887 val
1888 }),
1889 9u16 => FlowAttrs::Ufid({
1890 let res = Some(next);
1891 let Some(val) = res else { break };
1892 val
1893 }),
1894 10u16 => FlowAttrs::UfidFlags({
1895 let res = parse_u32(next);
1896 let Some(val) = res else { break };
1897 val
1898 }),
1899 11u16 => FlowAttrs::Pad({
1900 let res = Some(next);
1901 let Some(val) = res else { break };
1902 val
1903 }),
1904 n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
1905 n => continue,
1906 };
1907 return Some(Ok(res));
1908 }
1909 Some(Err(ErrorContext::new(
1910 "FlowAttrs",
1911 r#type.and_then(|t| FlowAttrs::attr_from_type(t)),
1912 self.orig_loc,
1913 self.buf.as_ptr().wrapping_add(pos) as usize,
1914 )))
1915 }
1916}
1917impl<'a> std::fmt::Debug for IterableFlowAttrs<'_> {
1918 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1919 let mut fmt = f.debug_struct("FlowAttrs");
1920 for attr in self.clone() {
1921 let attr = match attr {
1922 Ok(a) => a,
1923 Err(err) => {
1924 fmt.finish()?;
1925 f.write_str("Err(")?;
1926 err.fmt(f)?;
1927 return f.write_str(")");
1928 }
1929 };
1930 match attr {
1931 FlowAttrs::Key(val) => fmt.field("Key", &val),
1932 FlowAttrs::Actions(val) => fmt.field("Actions", &val),
1933 FlowAttrs::Stats(val) => fmt.field("Stats", &val),
1934 FlowAttrs::TcpFlags(val) => fmt.field("TcpFlags", &val),
1935 FlowAttrs::Used(val) => fmt.field("Used", &val),
1936 FlowAttrs::Clear(val) => fmt.field("Clear", &val),
1937 FlowAttrs::Mask(val) => fmt.field("Mask", &val),
1938 FlowAttrs::Probe(val) => fmt.field("Probe", &val),
1939 FlowAttrs::Ufid(val) => fmt.field("Ufid", &val),
1940 FlowAttrs::UfidFlags(val) => fmt.field(
1941 "UfidFlags",
1942 &FormatFlags(val.into(), OvsUfidFlags::from_value),
1943 ),
1944 FlowAttrs::Pad(val) => fmt.field("Pad", &val),
1945 };
1946 }
1947 fmt.finish()
1948 }
1949}
1950impl IterableFlowAttrs<'_> {
1951 pub fn lookup_attr(
1952 &self,
1953 offset: usize,
1954 missing_type: Option<u16>,
1955 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
1956 let mut stack = Vec::new();
1957 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
1958 if missing_type.is_some() && cur == offset {
1959 stack.push(("FlowAttrs", offset));
1960 return (
1961 stack,
1962 missing_type.and_then(|t| FlowAttrs::attr_from_type(t)),
1963 );
1964 }
1965 if cur > offset || cur + self.buf.len() < offset {
1966 return (stack, None);
1967 }
1968 let mut attrs = self.clone();
1969 let mut last_off = cur + attrs.pos;
1970 let mut missing = None;
1971 while let Some(attr) = attrs.next() {
1972 let Ok(attr) = attr else { break };
1973 match attr {
1974 FlowAttrs::Key(val) => {
1975 (stack, missing) = val.lookup_attr(offset, missing_type);
1976 if !stack.is_empty() {
1977 break;
1978 }
1979 }
1980 FlowAttrs::Actions(val) => {
1981 (stack, missing) = val.lookup_attr(offset, missing_type);
1982 if !stack.is_empty() {
1983 break;
1984 }
1985 }
1986 FlowAttrs::Stats(val) => {
1987 if last_off == offset {
1988 stack.push(("Stats", last_off));
1989 break;
1990 }
1991 }
1992 FlowAttrs::TcpFlags(val) => {
1993 if last_off == offset {
1994 stack.push(("TcpFlags", last_off));
1995 break;
1996 }
1997 }
1998 FlowAttrs::Used(val) => {
1999 if last_off == offset {
2000 stack.push(("Used", last_off));
2001 break;
2002 }
2003 }
2004 FlowAttrs::Clear(val) => {
2005 if last_off == offset {
2006 stack.push(("Clear", last_off));
2007 break;
2008 }
2009 }
2010 FlowAttrs::Mask(val) => {
2011 (stack, missing) = val.lookup_attr(offset, missing_type);
2012 if !stack.is_empty() {
2013 break;
2014 }
2015 }
2016 FlowAttrs::Probe(val) => {
2017 if last_off == offset {
2018 stack.push(("Probe", last_off));
2019 break;
2020 }
2021 }
2022 FlowAttrs::Ufid(val) => {
2023 if last_off == offset {
2024 stack.push(("Ufid", last_off));
2025 break;
2026 }
2027 }
2028 FlowAttrs::UfidFlags(val) => {
2029 if last_off == offset {
2030 stack.push(("UfidFlags", last_off));
2031 break;
2032 }
2033 }
2034 FlowAttrs::Pad(val) => {
2035 if last_off == offset {
2036 stack.push(("Pad", last_off));
2037 break;
2038 }
2039 }
2040 _ => {}
2041 };
2042 last_off = cur + attrs.pos;
2043 }
2044 if !stack.is_empty() {
2045 stack.push(("FlowAttrs", cur));
2046 }
2047 (stack, missing)
2048 }
2049}
2050#[derive(Clone)]
2051pub enum KeyAttrs<'a> {
2052 Encap(IterableKeyAttrs<'a>),
2053 Priority(u32),
2054 InPort(u32),
2055 #[doc = "struct ovs_key_ethernet\n"]
2056 Ethernet(OvsKeyEthernet),
2057 Vlan(u16),
2058 Ethertype(u16),
2059 Ipv4(OvsKeyIpv4),
2060 #[doc = "struct ovs_key_ipv6\n"]
2061 Ipv6(OvsKeyIpv6),
2062 Tcp(OvsKeyTcp),
2063 Udp(OvsKeyUdp),
2064 Icmp(OvsKeyIcmp),
2065 Icmpv6(OvsKeyIcmp),
2066 #[doc = "struct ovs_key_arp\n"]
2067 Arp(OvsKeyArp),
2068 #[doc = "struct ovs_key_nd\n"]
2069 Nd(OvsKeyNd),
2070 SkbMark(u32),
2071 Tunnel(IterableTunnelKeyAttrs<'a>),
2072 Sctp(OvsKeySctp),
2073 TcpFlags(u16),
2074 #[doc = "Value 0 indicates the hash is not computed by the datapath.\n"]
2075 DpHash(u32),
2076 RecircId(u32),
2077 Mpls(OvsKeyMpls),
2078 #[doc = "Associated type: [`CtStateFlags`] (1 bit per enumeration)"]
2079 CtState(u32),
2080 #[doc = "connection tracking zone\n"]
2081 CtZone(u16),
2082 #[doc = "connection tracking mark\n"]
2083 CtMark(u32),
2084 #[doc = "16-octet connection tracking label\n"]
2085 CtLabels(&'a [u8]),
2086 CtOrigTupleIpv4(OvsKeyCtTupleIpv4),
2087 #[doc = "struct ovs_key_ct_tuple_ipv6\n"]
2088 CtOrigTupleIpv6(&'a [u8]),
2089 Nsh(IterableOvsNshKeyAttrs<'a>),
2090 #[doc = "Should not be sent to the kernel\n"]
2091 PacketType(u32),
2092 #[doc = "Should not be sent to the kernel\n"]
2093 NdExtensions(&'a [u8]),
2094 #[doc = "struct ip_tunnel_info\n"]
2095 TunnelInfo(&'a [u8]),
2096 #[doc = "struct ovs_key_ipv6_exthdr\n"]
2097 Ipv6Exthdrs(OvsKeyIpv6Exthdrs),
2098}
2099impl<'a> IterableKeyAttrs<'a> {
2100 pub fn get_encap(&self) -> Result<IterableKeyAttrs<'a>, ErrorContext> {
2101 let mut iter = self.clone();
2102 iter.pos = 0;
2103 for attr in iter {
2104 if let Ok(KeyAttrs::Encap(val)) = attr {
2105 return Ok(val);
2106 }
2107 }
2108 Err(ErrorContext::new_missing(
2109 "KeyAttrs",
2110 "Encap",
2111 self.orig_loc,
2112 self.buf.as_ptr() as usize,
2113 ))
2114 }
2115 pub fn get_priority(&self) -> Result<u32, ErrorContext> {
2116 let mut iter = self.clone();
2117 iter.pos = 0;
2118 for attr in iter {
2119 if let Ok(KeyAttrs::Priority(val)) = attr {
2120 return Ok(val);
2121 }
2122 }
2123 Err(ErrorContext::new_missing(
2124 "KeyAttrs",
2125 "Priority",
2126 self.orig_loc,
2127 self.buf.as_ptr() as usize,
2128 ))
2129 }
2130 pub fn get_in_port(&self) -> Result<u32, ErrorContext> {
2131 let mut iter = self.clone();
2132 iter.pos = 0;
2133 for attr in iter {
2134 if let Ok(KeyAttrs::InPort(val)) = attr {
2135 return Ok(val);
2136 }
2137 }
2138 Err(ErrorContext::new_missing(
2139 "KeyAttrs",
2140 "InPort",
2141 self.orig_loc,
2142 self.buf.as_ptr() as usize,
2143 ))
2144 }
2145 #[doc = "struct ovs_key_ethernet\n"]
2146 pub fn get_ethernet(&self) -> Result<OvsKeyEthernet, ErrorContext> {
2147 let mut iter = self.clone();
2148 iter.pos = 0;
2149 for attr in iter {
2150 if let Ok(KeyAttrs::Ethernet(val)) = attr {
2151 return Ok(val);
2152 }
2153 }
2154 Err(ErrorContext::new_missing(
2155 "KeyAttrs",
2156 "Ethernet",
2157 self.orig_loc,
2158 self.buf.as_ptr() as usize,
2159 ))
2160 }
2161 pub fn get_vlan(&self) -> Result<u16, ErrorContext> {
2162 let mut iter = self.clone();
2163 iter.pos = 0;
2164 for attr in iter {
2165 if let Ok(KeyAttrs::Vlan(val)) = attr {
2166 return Ok(val);
2167 }
2168 }
2169 Err(ErrorContext::new_missing(
2170 "KeyAttrs",
2171 "Vlan",
2172 self.orig_loc,
2173 self.buf.as_ptr() as usize,
2174 ))
2175 }
2176 pub fn get_ethertype(&self) -> Result<u16, ErrorContext> {
2177 let mut iter = self.clone();
2178 iter.pos = 0;
2179 for attr in iter {
2180 if let Ok(KeyAttrs::Ethertype(val)) = attr {
2181 return Ok(val);
2182 }
2183 }
2184 Err(ErrorContext::new_missing(
2185 "KeyAttrs",
2186 "Ethertype",
2187 self.orig_loc,
2188 self.buf.as_ptr() as usize,
2189 ))
2190 }
2191 pub fn get_ipv4(&self) -> Result<OvsKeyIpv4, ErrorContext> {
2192 let mut iter = self.clone();
2193 iter.pos = 0;
2194 for attr in iter {
2195 if let Ok(KeyAttrs::Ipv4(val)) = attr {
2196 return Ok(val);
2197 }
2198 }
2199 Err(ErrorContext::new_missing(
2200 "KeyAttrs",
2201 "Ipv4",
2202 self.orig_loc,
2203 self.buf.as_ptr() as usize,
2204 ))
2205 }
2206 #[doc = "struct ovs_key_ipv6\n"]
2207 pub fn get_ipv6(&self) -> Result<OvsKeyIpv6, ErrorContext> {
2208 let mut iter = self.clone();
2209 iter.pos = 0;
2210 for attr in iter {
2211 if let Ok(KeyAttrs::Ipv6(val)) = attr {
2212 return Ok(val);
2213 }
2214 }
2215 Err(ErrorContext::new_missing(
2216 "KeyAttrs",
2217 "Ipv6",
2218 self.orig_loc,
2219 self.buf.as_ptr() as usize,
2220 ))
2221 }
2222 pub fn get_tcp(&self) -> Result<OvsKeyTcp, ErrorContext> {
2223 let mut iter = self.clone();
2224 iter.pos = 0;
2225 for attr in iter {
2226 if let Ok(KeyAttrs::Tcp(val)) = attr {
2227 return Ok(val);
2228 }
2229 }
2230 Err(ErrorContext::new_missing(
2231 "KeyAttrs",
2232 "Tcp",
2233 self.orig_loc,
2234 self.buf.as_ptr() as usize,
2235 ))
2236 }
2237 pub fn get_udp(&self) -> Result<OvsKeyUdp, ErrorContext> {
2238 let mut iter = self.clone();
2239 iter.pos = 0;
2240 for attr in iter {
2241 if let Ok(KeyAttrs::Udp(val)) = attr {
2242 return Ok(val);
2243 }
2244 }
2245 Err(ErrorContext::new_missing(
2246 "KeyAttrs",
2247 "Udp",
2248 self.orig_loc,
2249 self.buf.as_ptr() as usize,
2250 ))
2251 }
2252 pub fn get_icmp(&self) -> Result<OvsKeyIcmp, ErrorContext> {
2253 let mut iter = self.clone();
2254 iter.pos = 0;
2255 for attr in iter {
2256 if let Ok(KeyAttrs::Icmp(val)) = attr {
2257 return Ok(val);
2258 }
2259 }
2260 Err(ErrorContext::new_missing(
2261 "KeyAttrs",
2262 "Icmp",
2263 self.orig_loc,
2264 self.buf.as_ptr() as usize,
2265 ))
2266 }
2267 pub fn get_icmpv6(&self) -> Result<OvsKeyIcmp, ErrorContext> {
2268 let mut iter = self.clone();
2269 iter.pos = 0;
2270 for attr in iter {
2271 if let Ok(KeyAttrs::Icmpv6(val)) = attr {
2272 return Ok(val);
2273 }
2274 }
2275 Err(ErrorContext::new_missing(
2276 "KeyAttrs",
2277 "Icmpv6",
2278 self.orig_loc,
2279 self.buf.as_ptr() as usize,
2280 ))
2281 }
2282 #[doc = "struct ovs_key_arp\n"]
2283 pub fn get_arp(&self) -> Result<OvsKeyArp, ErrorContext> {
2284 let mut iter = self.clone();
2285 iter.pos = 0;
2286 for attr in iter {
2287 if let Ok(KeyAttrs::Arp(val)) = attr {
2288 return Ok(val);
2289 }
2290 }
2291 Err(ErrorContext::new_missing(
2292 "KeyAttrs",
2293 "Arp",
2294 self.orig_loc,
2295 self.buf.as_ptr() as usize,
2296 ))
2297 }
2298 #[doc = "struct ovs_key_nd\n"]
2299 pub fn get_nd(&self) -> Result<OvsKeyNd, ErrorContext> {
2300 let mut iter = self.clone();
2301 iter.pos = 0;
2302 for attr in iter {
2303 if let Ok(KeyAttrs::Nd(val)) = attr {
2304 return Ok(val);
2305 }
2306 }
2307 Err(ErrorContext::new_missing(
2308 "KeyAttrs",
2309 "Nd",
2310 self.orig_loc,
2311 self.buf.as_ptr() as usize,
2312 ))
2313 }
2314 pub fn get_skb_mark(&self) -> Result<u32, ErrorContext> {
2315 let mut iter = self.clone();
2316 iter.pos = 0;
2317 for attr in iter {
2318 if let Ok(KeyAttrs::SkbMark(val)) = attr {
2319 return Ok(val);
2320 }
2321 }
2322 Err(ErrorContext::new_missing(
2323 "KeyAttrs",
2324 "SkbMark",
2325 self.orig_loc,
2326 self.buf.as_ptr() as usize,
2327 ))
2328 }
2329 pub fn get_tunnel(&self) -> Result<IterableTunnelKeyAttrs<'a>, ErrorContext> {
2330 let mut iter = self.clone();
2331 iter.pos = 0;
2332 for attr in iter {
2333 if let Ok(KeyAttrs::Tunnel(val)) = attr {
2334 return Ok(val);
2335 }
2336 }
2337 Err(ErrorContext::new_missing(
2338 "KeyAttrs",
2339 "Tunnel",
2340 self.orig_loc,
2341 self.buf.as_ptr() as usize,
2342 ))
2343 }
2344 pub fn get_sctp(&self) -> Result<OvsKeySctp, ErrorContext> {
2345 let mut iter = self.clone();
2346 iter.pos = 0;
2347 for attr in iter {
2348 if let Ok(KeyAttrs::Sctp(val)) = attr {
2349 return Ok(val);
2350 }
2351 }
2352 Err(ErrorContext::new_missing(
2353 "KeyAttrs",
2354 "Sctp",
2355 self.orig_loc,
2356 self.buf.as_ptr() as usize,
2357 ))
2358 }
2359 pub fn get_tcp_flags(&self) -> Result<u16, ErrorContext> {
2360 let mut iter = self.clone();
2361 iter.pos = 0;
2362 for attr in iter {
2363 if let Ok(KeyAttrs::TcpFlags(val)) = attr {
2364 return Ok(val);
2365 }
2366 }
2367 Err(ErrorContext::new_missing(
2368 "KeyAttrs",
2369 "TcpFlags",
2370 self.orig_loc,
2371 self.buf.as_ptr() as usize,
2372 ))
2373 }
2374 #[doc = "Value 0 indicates the hash is not computed by the datapath.\n"]
2375 pub fn get_dp_hash(&self) -> Result<u32, ErrorContext> {
2376 let mut iter = self.clone();
2377 iter.pos = 0;
2378 for attr in iter {
2379 if let Ok(KeyAttrs::DpHash(val)) = attr {
2380 return Ok(val);
2381 }
2382 }
2383 Err(ErrorContext::new_missing(
2384 "KeyAttrs",
2385 "DpHash",
2386 self.orig_loc,
2387 self.buf.as_ptr() as usize,
2388 ))
2389 }
2390 pub fn get_recirc_id(&self) -> Result<u32, ErrorContext> {
2391 let mut iter = self.clone();
2392 iter.pos = 0;
2393 for attr in iter {
2394 if let Ok(KeyAttrs::RecircId(val)) = attr {
2395 return Ok(val);
2396 }
2397 }
2398 Err(ErrorContext::new_missing(
2399 "KeyAttrs",
2400 "RecircId",
2401 self.orig_loc,
2402 self.buf.as_ptr() as usize,
2403 ))
2404 }
2405 pub fn get_mpls(&self) -> Result<OvsKeyMpls, ErrorContext> {
2406 let mut iter = self.clone();
2407 iter.pos = 0;
2408 for attr in iter {
2409 if let Ok(KeyAttrs::Mpls(val)) = attr {
2410 return Ok(val);
2411 }
2412 }
2413 Err(ErrorContext::new_missing(
2414 "KeyAttrs",
2415 "Mpls",
2416 self.orig_loc,
2417 self.buf.as_ptr() as usize,
2418 ))
2419 }
2420 #[doc = "Associated type: [`CtStateFlags`] (1 bit per enumeration)"]
2421 pub fn get_ct_state(&self) -> Result<u32, ErrorContext> {
2422 let mut iter = self.clone();
2423 iter.pos = 0;
2424 for attr in iter {
2425 if let Ok(KeyAttrs::CtState(val)) = attr {
2426 return Ok(val);
2427 }
2428 }
2429 Err(ErrorContext::new_missing(
2430 "KeyAttrs",
2431 "CtState",
2432 self.orig_loc,
2433 self.buf.as_ptr() as usize,
2434 ))
2435 }
2436 #[doc = "connection tracking zone\n"]
2437 pub fn get_ct_zone(&self) -> Result<u16, ErrorContext> {
2438 let mut iter = self.clone();
2439 iter.pos = 0;
2440 for attr in iter {
2441 if let Ok(KeyAttrs::CtZone(val)) = attr {
2442 return Ok(val);
2443 }
2444 }
2445 Err(ErrorContext::new_missing(
2446 "KeyAttrs",
2447 "CtZone",
2448 self.orig_loc,
2449 self.buf.as_ptr() as usize,
2450 ))
2451 }
2452 #[doc = "connection tracking mark\n"]
2453 pub fn get_ct_mark(&self) -> Result<u32, ErrorContext> {
2454 let mut iter = self.clone();
2455 iter.pos = 0;
2456 for attr in iter {
2457 if let Ok(KeyAttrs::CtMark(val)) = attr {
2458 return Ok(val);
2459 }
2460 }
2461 Err(ErrorContext::new_missing(
2462 "KeyAttrs",
2463 "CtMark",
2464 self.orig_loc,
2465 self.buf.as_ptr() as usize,
2466 ))
2467 }
2468 #[doc = "16-octet connection tracking label\n"]
2469 pub fn get_ct_labels(&self) -> Result<&'a [u8], ErrorContext> {
2470 let mut iter = self.clone();
2471 iter.pos = 0;
2472 for attr in iter {
2473 if let Ok(KeyAttrs::CtLabels(val)) = attr {
2474 return Ok(val);
2475 }
2476 }
2477 Err(ErrorContext::new_missing(
2478 "KeyAttrs",
2479 "CtLabels",
2480 self.orig_loc,
2481 self.buf.as_ptr() as usize,
2482 ))
2483 }
2484 pub fn get_ct_orig_tuple_ipv4(&self) -> Result<OvsKeyCtTupleIpv4, ErrorContext> {
2485 let mut iter = self.clone();
2486 iter.pos = 0;
2487 for attr in iter {
2488 if let Ok(KeyAttrs::CtOrigTupleIpv4(val)) = attr {
2489 return Ok(val);
2490 }
2491 }
2492 Err(ErrorContext::new_missing(
2493 "KeyAttrs",
2494 "CtOrigTupleIpv4",
2495 self.orig_loc,
2496 self.buf.as_ptr() as usize,
2497 ))
2498 }
2499 #[doc = "struct ovs_key_ct_tuple_ipv6\n"]
2500 pub fn get_ct_orig_tuple_ipv6(&self) -> Result<&'a [u8], ErrorContext> {
2501 let mut iter = self.clone();
2502 iter.pos = 0;
2503 for attr in iter {
2504 if let Ok(KeyAttrs::CtOrigTupleIpv6(val)) = attr {
2505 return Ok(val);
2506 }
2507 }
2508 Err(ErrorContext::new_missing(
2509 "KeyAttrs",
2510 "CtOrigTupleIpv6",
2511 self.orig_loc,
2512 self.buf.as_ptr() as usize,
2513 ))
2514 }
2515 pub fn get_nsh(&self) -> Result<IterableOvsNshKeyAttrs<'a>, ErrorContext> {
2516 let mut iter = self.clone();
2517 iter.pos = 0;
2518 for attr in iter {
2519 if let Ok(KeyAttrs::Nsh(val)) = attr {
2520 return Ok(val);
2521 }
2522 }
2523 Err(ErrorContext::new_missing(
2524 "KeyAttrs",
2525 "Nsh",
2526 self.orig_loc,
2527 self.buf.as_ptr() as usize,
2528 ))
2529 }
2530 #[doc = "Should not be sent to the kernel\n"]
2531 pub fn get_packet_type(&self) -> Result<u32, ErrorContext> {
2532 let mut iter = self.clone();
2533 iter.pos = 0;
2534 for attr in iter {
2535 if let Ok(KeyAttrs::PacketType(val)) = attr {
2536 return Ok(val);
2537 }
2538 }
2539 Err(ErrorContext::new_missing(
2540 "KeyAttrs",
2541 "PacketType",
2542 self.orig_loc,
2543 self.buf.as_ptr() as usize,
2544 ))
2545 }
2546 #[doc = "Should not be sent to the kernel\n"]
2547 pub fn get_nd_extensions(&self) -> Result<&'a [u8], ErrorContext> {
2548 let mut iter = self.clone();
2549 iter.pos = 0;
2550 for attr in iter {
2551 if let Ok(KeyAttrs::NdExtensions(val)) = attr {
2552 return Ok(val);
2553 }
2554 }
2555 Err(ErrorContext::new_missing(
2556 "KeyAttrs",
2557 "NdExtensions",
2558 self.orig_loc,
2559 self.buf.as_ptr() as usize,
2560 ))
2561 }
2562 #[doc = "struct ip_tunnel_info\n"]
2563 pub fn get_tunnel_info(&self) -> Result<&'a [u8], ErrorContext> {
2564 let mut iter = self.clone();
2565 iter.pos = 0;
2566 for attr in iter {
2567 if let Ok(KeyAttrs::TunnelInfo(val)) = attr {
2568 return Ok(val);
2569 }
2570 }
2571 Err(ErrorContext::new_missing(
2572 "KeyAttrs",
2573 "TunnelInfo",
2574 self.orig_loc,
2575 self.buf.as_ptr() as usize,
2576 ))
2577 }
2578 #[doc = "struct ovs_key_ipv6_exthdr\n"]
2579 pub fn get_ipv6_exthdrs(&self) -> Result<OvsKeyIpv6Exthdrs, ErrorContext> {
2580 let mut iter = self.clone();
2581 iter.pos = 0;
2582 for attr in iter {
2583 if let Ok(KeyAttrs::Ipv6Exthdrs(val)) = attr {
2584 return Ok(val);
2585 }
2586 }
2587 Err(ErrorContext::new_missing(
2588 "KeyAttrs",
2589 "Ipv6Exthdrs",
2590 self.orig_loc,
2591 self.buf.as_ptr() as usize,
2592 ))
2593 }
2594}
2595impl KeyAttrs<'_> {
2596 pub fn new<'a>(buf: &'a [u8]) -> IterableKeyAttrs<'a> {
2597 IterableKeyAttrs::with_loc(buf, buf.as_ptr() as usize)
2598 }
2599 fn attr_from_type(r#type: u16) -> Option<&'static str> {
2600 let res = match r#type {
2601 1u16 => "Encap",
2602 2u16 => "Priority",
2603 3u16 => "InPort",
2604 4u16 => "Ethernet",
2605 5u16 => "Vlan",
2606 6u16 => "Ethertype",
2607 7u16 => "Ipv4",
2608 8u16 => "Ipv6",
2609 9u16 => "Tcp",
2610 10u16 => "Udp",
2611 11u16 => "Icmp",
2612 12u16 => "Icmpv6",
2613 13u16 => "Arp",
2614 14u16 => "Nd",
2615 15u16 => "SkbMark",
2616 16u16 => "Tunnel",
2617 17u16 => "Sctp",
2618 18u16 => "TcpFlags",
2619 19u16 => "DpHash",
2620 20u16 => "RecircId",
2621 21u16 => "Mpls",
2622 22u16 => "CtState",
2623 23u16 => "CtZone",
2624 24u16 => "CtMark",
2625 25u16 => "CtLabels",
2626 26u16 => "CtOrigTupleIpv4",
2627 27u16 => "CtOrigTupleIpv6",
2628 28u16 => "Nsh",
2629 29u16 => "PacketType",
2630 30u16 => "NdExtensions",
2631 31u16 => "TunnelInfo",
2632 32u16 => "Ipv6Exthdrs",
2633 _ => return None,
2634 };
2635 Some(res)
2636 }
2637}
2638#[derive(Clone, Copy, Default)]
2639pub struct IterableKeyAttrs<'a> {
2640 buf: &'a [u8],
2641 pos: usize,
2642 orig_loc: usize,
2643}
2644impl<'a> IterableKeyAttrs<'a> {
2645 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
2646 Self {
2647 buf,
2648 pos: 0,
2649 orig_loc,
2650 }
2651 }
2652 pub fn get_buf(&self) -> &'a [u8] {
2653 self.buf
2654 }
2655}
2656impl<'a> Iterator for IterableKeyAttrs<'a> {
2657 type Item = Result<KeyAttrs<'a>, ErrorContext>;
2658 fn next(&mut self) -> Option<Self::Item> {
2659 let mut pos;
2660 let mut r#type;
2661 loop {
2662 pos = self.pos;
2663 r#type = None;
2664 if self.buf.len() == self.pos {
2665 return None;
2666 }
2667 let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
2668 self.pos = self.buf.len();
2669 break;
2670 };
2671 r#type = Some(header.r#type);
2672 let res = match header.r#type {
2673 1u16 => KeyAttrs::Encap({
2674 let res = Some(IterableKeyAttrs::with_loc(next, self.orig_loc));
2675 let Some(val) = res else { break };
2676 val
2677 }),
2678 2u16 => KeyAttrs::Priority({
2679 let res = parse_u32(next);
2680 let Some(val) = res else { break };
2681 val
2682 }),
2683 3u16 => KeyAttrs::InPort({
2684 let res = parse_u32(next);
2685 let Some(val) = res else { break };
2686 val
2687 }),
2688 4u16 => KeyAttrs::Ethernet({
2689 let res = Some(OvsKeyEthernet::new_from_zeroed(next));
2690 let Some(val) = res else { break };
2691 val
2692 }),
2693 5u16 => KeyAttrs::Vlan({
2694 let res = parse_be_u16(next);
2695 let Some(val) = res else { break };
2696 val
2697 }),
2698 6u16 => KeyAttrs::Ethertype({
2699 let res = parse_be_u16(next);
2700 let Some(val) = res else { break };
2701 val
2702 }),
2703 7u16 => KeyAttrs::Ipv4({
2704 let res = Some(OvsKeyIpv4::new_from_zeroed(next));
2705 let Some(val) = res else { break };
2706 val
2707 }),
2708 8u16 => KeyAttrs::Ipv6({
2709 let res = Some(OvsKeyIpv6::new_from_zeroed(next));
2710 let Some(val) = res else { break };
2711 val
2712 }),
2713 9u16 => KeyAttrs::Tcp({
2714 let res = Some(OvsKeyTcp::new_from_zeroed(next));
2715 let Some(val) = res else { break };
2716 val
2717 }),
2718 10u16 => KeyAttrs::Udp({
2719 let res = Some(OvsKeyUdp::new_from_zeroed(next));
2720 let Some(val) = res else { break };
2721 val
2722 }),
2723 11u16 => KeyAttrs::Icmp({
2724 let res = Some(OvsKeyIcmp::new_from_zeroed(next));
2725 let Some(val) = res else { break };
2726 val
2727 }),
2728 12u16 => KeyAttrs::Icmpv6({
2729 let res = Some(OvsKeyIcmp::new_from_zeroed(next));
2730 let Some(val) = res else { break };
2731 val
2732 }),
2733 13u16 => KeyAttrs::Arp({
2734 let res = Some(OvsKeyArp::new_from_zeroed(next));
2735 let Some(val) = res else { break };
2736 val
2737 }),
2738 14u16 => KeyAttrs::Nd({
2739 let res = Some(OvsKeyNd::new_from_zeroed(next));
2740 let Some(val) = res else { break };
2741 val
2742 }),
2743 15u16 => KeyAttrs::SkbMark({
2744 let res = parse_u32(next);
2745 let Some(val) = res else { break };
2746 val
2747 }),
2748 16u16 => KeyAttrs::Tunnel({
2749 let res = Some(IterableTunnelKeyAttrs::with_loc(next, self.orig_loc));
2750 let Some(val) = res else { break };
2751 val
2752 }),
2753 17u16 => KeyAttrs::Sctp({
2754 let res = Some(OvsKeySctp::new_from_zeroed(next));
2755 let Some(val) = res else { break };
2756 val
2757 }),
2758 18u16 => KeyAttrs::TcpFlags({
2759 let res = parse_be_u16(next);
2760 let Some(val) = res else { break };
2761 val
2762 }),
2763 19u16 => KeyAttrs::DpHash({
2764 let res = parse_u32(next);
2765 let Some(val) = res else { break };
2766 val
2767 }),
2768 20u16 => KeyAttrs::RecircId({
2769 let res = parse_u32(next);
2770 let Some(val) = res else { break };
2771 val
2772 }),
2773 21u16 => KeyAttrs::Mpls({
2774 let res = Some(OvsKeyMpls::new_from_zeroed(next));
2775 let Some(val) = res else { break };
2776 val
2777 }),
2778 22u16 => KeyAttrs::CtState({
2779 let res = parse_u32(next);
2780 let Some(val) = res else { break };
2781 val
2782 }),
2783 23u16 => KeyAttrs::CtZone({
2784 let res = parse_u16(next);
2785 let Some(val) = res else { break };
2786 val
2787 }),
2788 24u16 => KeyAttrs::CtMark({
2789 let res = parse_u32(next);
2790 let Some(val) = res else { break };
2791 val
2792 }),
2793 25u16 => KeyAttrs::CtLabels({
2794 let res = Some(next);
2795 let Some(val) = res else { break };
2796 val
2797 }),
2798 26u16 => KeyAttrs::CtOrigTupleIpv4({
2799 let res = Some(OvsKeyCtTupleIpv4::new_from_zeroed(next));
2800 let Some(val) = res else { break };
2801 val
2802 }),
2803 27u16 => KeyAttrs::CtOrigTupleIpv6({
2804 let res = Some(next);
2805 let Some(val) = res else { break };
2806 val
2807 }),
2808 28u16 => KeyAttrs::Nsh({
2809 let res = Some(IterableOvsNshKeyAttrs::with_loc(next, self.orig_loc));
2810 let Some(val) = res else { break };
2811 val
2812 }),
2813 29u16 => KeyAttrs::PacketType({
2814 let res = parse_be_u32(next);
2815 let Some(val) = res else { break };
2816 val
2817 }),
2818 30u16 => KeyAttrs::NdExtensions({
2819 let res = Some(next);
2820 let Some(val) = res else { break };
2821 val
2822 }),
2823 31u16 => KeyAttrs::TunnelInfo({
2824 let res = Some(next);
2825 let Some(val) = res else { break };
2826 val
2827 }),
2828 32u16 => KeyAttrs::Ipv6Exthdrs({
2829 let res = Some(OvsKeyIpv6Exthdrs::new_from_zeroed(next));
2830 let Some(val) = res else { break };
2831 val
2832 }),
2833 n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
2834 n => continue,
2835 };
2836 return Some(Ok(res));
2837 }
2838 Some(Err(ErrorContext::new(
2839 "KeyAttrs",
2840 r#type.and_then(|t| KeyAttrs::attr_from_type(t)),
2841 self.orig_loc,
2842 self.buf.as_ptr().wrapping_add(pos) as usize,
2843 )))
2844 }
2845}
2846impl<'a> std::fmt::Debug for IterableKeyAttrs<'_> {
2847 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2848 let mut fmt = f.debug_struct("KeyAttrs");
2849 for attr in self.clone() {
2850 let attr = match attr {
2851 Ok(a) => a,
2852 Err(err) => {
2853 fmt.finish()?;
2854 f.write_str("Err(")?;
2855 err.fmt(f)?;
2856 return f.write_str(")");
2857 }
2858 };
2859 match attr {
2860 KeyAttrs::Encap(val) => fmt.field("Encap", &val),
2861 KeyAttrs::Priority(val) => fmt.field("Priority", &val),
2862 KeyAttrs::InPort(val) => fmt.field("InPort", &val),
2863 KeyAttrs::Ethernet(val) => fmt.field("Ethernet", &val),
2864 KeyAttrs::Vlan(val) => fmt.field("Vlan", &val),
2865 KeyAttrs::Ethertype(val) => fmt.field("Ethertype", &val),
2866 KeyAttrs::Ipv4(val) => fmt.field("Ipv4", &val),
2867 KeyAttrs::Ipv6(val) => fmt.field("Ipv6", &val),
2868 KeyAttrs::Tcp(val) => fmt.field("Tcp", &val),
2869 KeyAttrs::Udp(val) => fmt.field("Udp", &val),
2870 KeyAttrs::Icmp(val) => fmt.field("Icmp", &val),
2871 KeyAttrs::Icmpv6(val) => fmt.field("Icmpv6", &val),
2872 KeyAttrs::Arp(val) => fmt.field("Arp", &val),
2873 KeyAttrs::Nd(val) => fmt.field("Nd", &val),
2874 KeyAttrs::SkbMark(val) => fmt.field("SkbMark", &val),
2875 KeyAttrs::Tunnel(val) => fmt.field("Tunnel", &val),
2876 KeyAttrs::Sctp(val) => fmt.field("Sctp", &val),
2877 KeyAttrs::TcpFlags(val) => fmt.field("TcpFlags", &val),
2878 KeyAttrs::DpHash(val) => fmt.field("DpHash", &val),
2879 KeyAttrs::RecircId(val) => fmt.field("RecircId", &val),
2880 KeyAttrs::Mpls(val) => fmt.field("Mpls", &val),
2881 KeyAttrs::CtState(val) => fmt.field(
2882 "CtState",
2883 &FormatFlags(val.into(), CtStateFlags::from_value),
2884 ),
2885 KeyAttrs::CtZone(val) => fmt.field("CtZone", &val),
2886 KeyAttrs::CtMark(val) => fmt.field("CtMark", &val),
2887 KeyAttrs::CtLabels(val) => fmt.field("CtLabels", &FormatHex(val)),
2888 KeyAttrs::CtOrigTupleIpv4(val) => fmt.field("CtOrigTupleIpv4", &val),
2889 KeyAttrs::CtOrigTupleIpv6(val) => fmt.field("CtOrigTupleIpv6", &val),
2890 KeyAttrs::Nsh(val) => fmt.field("Nsh", &val),
2891 KeyAttrs::PacketType(val) => fmt.field("PacketType", &val),
2892 KeyAttrs::NdExtensions(val) => fmt.field("NdExtensions", &val),
2893 KeyAttrs::TunnelInfo(val) => fmt.field("TunnelInfo", &val),
2894 KeyAttrs::Ipv6Exthdrs(val) => fmt.field("Ipv6Exthdrs", &val),
2895 };
2896 }
2897 fmt.finish()
2898 }
2899}
2900impl IterableKeyAttrs<'_> {
2901 pub fn lookup_attr(
2902 &self,
2903 offset: usize,
2904 missing_type: Option<u16>,
2905 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
2906 let mut stack = Vec::new();
2907 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
2908 if missing_type.is_some() && cur == offset {
2909 stack.push(("KeyAttrs", offset));
2910 return (
2911 stack,
2912 missing_type.and_then(|t| KeyAttrs::attr_from_type(t)),
2913 );
2914 }
2915 if cur > offset || cur + self.buf.len() < offset {
2916 return (stack, None);
2917 }
2918 let mut attrs = self.clone();
2919 let mut last_off = cur + attrs.pos;
2920 let mut missing = None;
2921 while let Some(attr) = attrs.next() {
2922 let Ok(attr) = attr else { break };
2923 match attr {
2924 KeyAttrs::Encap(val) => {
2925 (stack, missing) = val.lookup_attr(offset, missing_type);
2926 if !stack.is_empty() {
2927 break;
2928 }
2929 }
2930 KeyAttrs::Priority(val) => {
2931 if last_off == offset {
2932 stack.push(("Priority", last_off));
2933 break;
2934 }
2935 }
2936 KeyAttrs::InPort(val) => {
2937 if last_off == offset {
2938 stack.push(("InPort", last_off));
2939 break;
2940 }
2941 }
2942 KeyAttrs::Ethernet(val) => {
2943 if last_off == offset {
2944 stack.push(("Ethernet", last_off));
2945 break;
2946 }
2947 }
2948 KeyAttrs::Vlan(val) => {
2949 if last_off == offset {
2950 stack.push(("Vlan", last_off));
2951 break;
2952 }
2953 }
2954 KeyAttrs::Ethertype(val) => {
2955 if last_off == offset {
2956 stack.push(("Ethertype", last_off));
2957 break;
2958 }
2959 }
2960 KeyAttrs::Ipv4(val) => {
2961 if last_off == offset {
2962 stack.push(("Ipv4", last_off));
2963 break;
2964 }
2965 }
2966 KeyAttrs::Ipv6(val) => {
2967 if last_off == offset {
2968 stack.push(("Ipv6", last_off));
2969 break;
2970 }
2971 }
2972 KeyAttrs::Tcp(val) => {
2973 if last_off == offset {
2974 stack.push(("Tcp", last_off));
2975 break;
2976 }
2977 }
2978 KeyAttrs::Udp(val) => {
2979 if last_off == offset {
2980 stack.push(("Udp", last_off));
2981 break;
2982 }
2983 }
2984 KeyAttrs::Icmp(val) => {
2985 if last_off == offset {
2986 stack.push(("Icmp", last_off));
2987 break;
2988 }
2989 }
2990 KeyAttrs::Icmpv6(val) => {
2991 if last_off == offset {
2992 stack.push(("Icmpv6", last_off));
2993 break;
2994 }
2995 }
2996 KeyAttrs::Arp(val) => {
2997 if last_off == offset {
2998 stack.push(("Arp", last_off));
2999 break;
3000 }
3001 }
3002 KeyAttrs::Nd(val) => {
3003 if last_off == offset {
3004 stack.push(("Nd", last_off));
3005 break;
3006 }
3007 }
3008 KeyAttrs::SkbMark(val) => {
3009 if last_off == offset {
3010 stack.push(("SkbMark", last_off));
3011 break;
3012 }
3013 }
3014 KeyAttrs::Tunnel(val) => {
3015 (stack, missing) = val.lookup_attr(offset, missing_type);
3016 if !stack.is_empty() {
3017 break;
3018 }
3019 }
3020 KeyAttrs::Sctp(val) => {
3021 if last_off == offset {
3022 stack.push(("Sctp", last_off));
3023 break;
3024 }
3025 }
3026 KeyAttrs::TcpFlags(val) => {
3027 if last_off == offset {
3028 stack.push(("TcpFlags", last_off));
3029 break;
3030 }
3031 }
3032 KeyAttrs::DpHash(val) => {
3033 if last_off == offset {
3034 stack.push(("DpHash", last_off));
3035 break;
3036 }
3037 }
3038 KeyAttrs::RecircId(val) => {
3039 if last_off == offset {
3040 stack.push(("RecircId", last_off));
3041 break;
3042 }
3043 }
3044 KeyAttrs::Mpls(val) => {
3045 if last_off == offset {
3046 stack.push(("Mpls", last_off));
3047 break;
3048 }
3049 }
3050 KeyAttrs::CtState(val) => {
3051 if last_off == offset {
3052 stack.push(("CtState", last_off));
3053 break;
3054 }
3055 }
3056 KeyAttrs::CtZone(val) => {
3057 if last_off == offset {
3058 stack.push(("CtZone", last_off));
3059 break;
3060 }
3061 }
3062 KeyAttrs::CtMark(val) => {
3063 if last_off == offset {
3064 stack.push(("CtMark", last_off));
3065 break;
3066 }
3067 }
3068 KeyAttrs::CtLabels(val) => {
3069 if last_off == offset {
3070 stack.push(("CtLabels", last_off));
3071 break;
3072 }
3073 }
3074 KeyAttrs::CtOrigTupleIpv4(val) => {
3075 if last_off == offset {
3076 stack.push(("CtOrigTupleIpv4", last_off));
3077 break;
3078 }
3079 }
3080 KeyAttrs::CtOrigTupleIpv6(val) => {
3081 if last_off == offset {
3082 stack.push(("CtOrigTupleIpv6", last_off));
3083 break;
3084 }
3085 }
3086 KeyAttrs::Nsh(val) => {
3087 (stack, missing) = val.lookup_attr(offset, missing_type);
3088 if !stack.is_empty() {
3089 break;
3090 }
3091 }
3092 KeyAttrs::PacketType(val) => {
3093 if last_off == offset {
3094 stack.push(("PacketType", last_off));
3095 break;
3096 }
3097 }
3098 KeyAttrs::NdExtensions(val) => {
3099 if last_off == offset {
3100 stack.push(("NdExtensions", last_off));
3101 break;
3102 }
3103 }
3104 KeyAttrs::TunnelInfo(val) => {
3105 if last_off == offset {
3106 stack.push(("TunnelInfo", last_off));
3107 break;
3108 }
3109 }
3110 KeyAttrs::Ipv6Exthdrs(val) => {
3111 if last_off == offset {
3112 stack.push(("Ipv6Exthdrs", last_off));
3113 break;
3114 }
3115 }
3116 _ => {}
3117 };
3118 last_off = cur + attrs.pos;
3119 }
3120 if !stack.is_empty() {
3121 stack.push(("KeyAttrs", cur));
3122 }
3123 (stack, missing)
3124 }
3125}
3126#[derive(Clone)]
3127pub enum ActionAttrs<'a> {
3128 #[doc = "ovs port number in datapath\n"]
3129 Output(u32),
3130 Userspace(IterableUserspaceAttrs<'a>),
3131 #[doc = "Replaces the contents of an existing header. The single nested attribute\nspecifies a header to modify and its value.\n"]
3132 Set(IterableKeyAttrs<'a>),
3133 #[doc = "Push a new outermost 802.1Q or 802.1ad header onto the packet.\n"]
3134 PushVlan(OvsActionPushVlan),
3135 #[doc = "Pop the outermost 802.1Q or 802.1ad header from the packet.\n"]
3136 PopVlan(()),
3137 #[doc = "Probabilistically executes actions, as specified in the nested\nattributes.\n"]
3138 Sample(IterableSampleAttrs<'a>),
3139 #[doc = "recirc id\n"]
3140 Recirc(u32),
3141 Hash(OvsActionHash),
3142 #[doc = "Push a new MPLS label stack entry onto the top of the packets MPLS label\nstack. Set the ethertype of the encapsulating frame to either\nETH_P_MPLS_UC or ETH_P_MPLS_MC to indicate the new packet contents.\n"]
3143 PushMpls(OvsActionPushMpls),
3144 #[doc = "ethertype\n"]
3145 PopMpls(u16),
3146 #[doc = "Replaces the contents of an existing header. A nested attribute\nspecifies a header to modify, its value, and a mask. For every bit set\nin the mask, the corresponding bit value is copied from the value to the\npacket header field, rest of the bits are left unchanged. The non-masked\nvalue bits must be passed in as zeroes. Masking is not supported for the\nOVS_KEY_ATTR_TUNNEL attribute.\n"]
3147 SetMasked(IterableKeyAttrs<'a>),
3148 #[doc = "Track the connection. Populate the conntrack-related entries in the flow\nkey.\n"]
3149 Ct(IterableCtAttrs<'a>),
3150 #[doc = "struct ovs_action_trunc is a u32 max length\n"]
3151 Trunc(u32),
3152 #[doc = "struct ovs_action_push_eth\n"]
3153 PushEth(&'a [u8]),
3154 PopEth(()),
3155 CtClear(()),
3156 #[doc = "Push NSH header to the packet.\n"]
3157 PushNsh(IterableOvsNshKeyAttrs<'a>),
3158 #[doc = "Pop the outermost NSH header off the packet.\n"]
3159 PopNsh(()),
3160 #[doc = "Run packet through a meter, which may drop the packet, or modify the\npacket (e.g., change the DSCP field)\n"]
3161 Meter(u32),
3162 #[doc = "Make a copy of the packet and execute a list of actions without\naffecting the original packet and key.\n"]
3163 Clone(IterableActionAttrs<'a>),
3164 #[doc = "Check the packet length and execute a set of actions if greater than the\nspecified packet length, else execute another set of actions.\n"]
3165 CheckPktLen(IterableCheckPktLenAttrs<'a>),
3166 #[doc = "Push a new MPLS label stack entry at the start of the packet or at the\nstart of the l3 header depending on the value of l3 tunnel flag in the\ntun_flags field of this OVS_ACTION_ATTR_ADD_MPLS argument.\n"]
3167 AddMpls(OvsActionAddMpls),
3168 DecTtl(IterableDecTtlAttrs<'a>),
3169 #[doc = "Sends a packet sample to psample for external observation.\n"]
3170 Psample(IterablePsampleAttrs<'a>),
3171}
3172impl<'a> IterableActionAttrs<'a> {
3173 #[doc = "ovs port number in datapath\n"]
3174 pub fn get_output(&self) -> Result<u32, ErrorContext> {
3175 let mut iter = self.clone();
3176 iter.pos = 0;
3177 for attr in iter {
3178 if let Ok(ActionAttrs::Output(val)) = attr {
3179 return Ok(val);
3180 }
3181 }
3182 Err(ErrorContext::new_missing(
3183 "ActionAttrs",
3184 "Output",
3185 self.orig_loc,
3186 self.buf.as_ptr() as usize,
3187 ))
3188 }
3189 pub fn get_userspace(&self) -> Result<IterableUserspaceAttrs<'a>, ErrorContext> {
3190 let mut iter = self.clone();
3191 iter.pos = 0;
3192 for attr in iter {
3193 if let Ok(ActionAttrs::Userspace(val)) = attr {
3194 return Ok(val);
3195 }
3196 }
3197 Err(ErrorContext::new_missing(
3198 "ActionAttrs",
3199 "Userspace",
3200 self.orig_loc,
3201 self.buf.as_ptr() as usize,
3202 ))
3203 }
3204 #[doc = "Replaces the contents of an existing header. The single nested attribute\nspecifies a header to modify and its value.\n"]
3205 pub fn get_set(&self) -> Result<IterableKeyAttrs<'a>, ErrorContext> {
3206 let mut iter = self.clone();
3207 iter.pos = 0;
3208 for attr in iter {
3209 if let Ok(ActionAttrs::Set(val)) = attr {
3210 return Ok(val);
3211 }
3212 }
3213 Err(ErrorContext::new_missing(
3214 "ActionAttrs",
3215 "Set",
3216 self.orig_loc,
3217 self.buf.as_ptr() as usize,
3218 ))
3219 }
3220 #[doc = "Push a new outermost 802.1Q or 802.1ad header onto the packet.\n"]
3221 pub fn get_push_vlan(&self) -> Result<OvsActionPushVlan, ErrorContext> {
3222 let mut iter = self.clone();
3223 iter.pos = 0;
3224 for attr in iter {
3225 if let Ok(ActionAttrs::PushVlan(val)) = attr {
3226 return Ok(val);
3227 }
3228 }
3229 Err(ErrorContext::new_missing(
3230 "ActionAttrs",
3231 "PushVlan",
3232 self.orig_loc,
3233 self.buf.as_ptr() as usize,
3234 ))
3235 }
3236 #[doc = "Pop the outermost 802.1Q or 802.1ad header from the packet.\n"]
3237 pub fn get_pop_vlan(&self) -> Result<(), ErrorContext> {
3238 let mut iter = self.clone();
3239 iter.pos = 0;
3240 for attr in iter {
3241 if let Ok(ActionAttrs::PopVlan(val)) = attr {
3242 return Ok(val);
3243 }
3244 }
3245 Err(ErrorContext::new_missing(
3246 "ActionAttrs",
3247 "PopVlan",
3248 self.orig_loc,
3249 self.buf.as_ptr() as usize,
3250 ))
3251 }
3252 #[doc = "Probabilistically executes actions, as specified in the nested\nattributes.\n"]
3253 pub fn get_sample(&self) -> Result<IterableSampleAttrs<'a>, ErrorContext> {
3254 let mut iter = self.clone();
3255 iter.pos = 0;
3256 for attr in iter {
3257 if let Ok(ActionAttrs::Sample(val)) = attr {
3258 return Ok(val);
3259 }
3260 }
3261 Err(ErrorContext::new_missing(
3262 "ActionAttrs",
3263 "Sample",
3264 self.orig_loc,
3265 self.buf.as_ptr() as usize,
3266 ))
3267 }
3268 #[doc = "recirc id\n"]
3269 pub fn get_recirc(&self) -> Result<u32, ErrorContext> {
3270 let mut iter = self.clone();
3271 iter.pos = 0;
3272 for attr in iter {
3273 if let Ok(ActionAttrs::Recirc(val)) = attr {
3274 return Ok(val);
3275 }
3276 }
3277 Err(ErrorContext::new_missing(
3278 "ActionAttrs",
3279 "Recirc",
3280 self.orig_loc,
3281 self.buf.as_ptr() as usize,
3282 ))
3283 }
3284 pub fn get_hash(&self) -> Result<OvsActionHash, ErrorContext> {
3285 let mut iter = self.clone();
3286 iter.pos = 0;
3287 for attr in iter {
3288 if let Ok(ActionAttrs::Hash(val)) = attr {
3289 return Ok(val);
3290 }
3291 }
3292 Err(ErrorContext::new_missing(
3293 "ActionAttrs",
3294 "Hash",
3295 self.orig_loc,
3296 self.buf.as_ptr() as usize,
3297 ))
3298 }
3299 #[doc = "Push a new MPLS label stack entry onto the top of the packets MPLS label\nstack. Set the ethertype of the encapsulating frame to either\nETH_P_MPLS_UC or ETH_P_MPLS_MC to indicate the new packet contents.\n"]
3300 pub fn get_push_mpls(&self) -> Result<OvsActionPushMpls, ErrorContext> {
3301 let mut iter = self.clone();
3302 iter.pos = 0;
3303 for attr in iter {
3304 if let Ok(ActionAttrs::PushMpls(val)) = attr {
3305 return Ok(val);
3306 }
3307 }
3308 Err(ErrorContext::new_missing(
3309 "ActionAttrs",
3310 "PushMpls",
3311 self.orig_loc,
3312 self.buf.as_ptr() as usize,
3313 ))
3314 }
3315 #[doc = "ethertype\n"]
3316 pub fn get_pop_mpls(&self) -> Result<u16, ErrorContext> {
3317 let mut iter = self.clone();
3318 iter.pos = 0;
3319 for attr in iter {
3320 if let Ok(ActionAttrs::PopMpls(val)) = attr {
3321 return Ok(val);
3322 }
3323 }
3324 Err(ErrorContext::new_missing(
3325 "ActionAttrs",
3326 "PopMpls",
3327 self.orig_loc,
3328 self.buf.as_ptr() as usize,
3329 ))
3330 }
3331 #[doc = "Replaces the contents of an existing header. A nested attribute\nspecifies a header to modify, its value, and a mask. For every bit set\nin the mask, the corresponding bit value is copied from the value to the\npacket header field, rest of the bits are left unchanged. The non-masked\nvalue bits must be passed in as zeroes. Masking is not supported for the\nOVS_KEY_ATTR_TUNNEL attribute.\n"]
3332 pub fn get_set_masked(&self) -> Result<IterableKeyAttrs<'a>, ErrorContext> {
3333 let mut iter = self.clone();
3334 iter.pos = 0;
3335 for attr in iter {
3336 if let Ok(ActionAttrs::SetMasked(val)) = attr {
3337 return Ok(val);
3338 }
3339 }
3340 Err(ErrorContext::new_missing(
3341 "ActionAttrs",
3342 "SetMasked",
3343 self.orig_loc,
3344 self.buf.as_ptr() as usize,
3345 ))
3346 }
3347 #[doc = "Track the connection. Populate the conntrack-related entries in the flow\nkey.\n"]
3348 pub fn get_ct(&self) -> Result<IterableCtAttrs<'a>, ErrorContext> {
3349 let mut iter = self.clone();
3350 iter.pos = 0;
3351 for attr in iter {
3352 if let Ok(ActionAttrs::Ct(val)) = attr {
3353 return Ok(val);
3354 }
3355 }
3356 Err(ErrorContext::new_missing(
3357 "ActionAttrs",
3358 "Ct",
3359 self.orig_loc,
3360 self.buf.as_ptr() as usize,
3361 ))
3362 }
3363 #[doc = "struct ovs_action_trunc is a u32 max length\n"]
3364 pub fn get_trunc(&self) -> Result<u32, ErrorContext> {
3365 let mut iter = self.clone();
3366 iter.pos = 0;
3367 for attr in iter {
3368 if let Ok(ActionAttrs::Trunc(val)) = attr {
3369 return Ok(val);
3370 }
3371 }
3372 Err(ErrorContext::new_missing(
3373 "ActionAttrs",
3374 "Trunc",
3375 self.orig_loc,
3376 self.buf.as_ptr() as usize,
3377 ))
3378 }
3379 #[doc = "struct ovs_action_push_eth\n"]
3380 pub fn get_push_eth(&self) -> Result<&'a [u8], ErrorContext> {
3381 let mut iter = self.clone();
3382 iter.pos = 0;
3383 for attr in iter {
3384 if let Ok(ActionAttrs::PushEth(val)) = attr {
3385 return Ok(val);
3386 }
3387 }
3388 Err(ErrorContext::new_missing(
3389 "ActionAttrs",
3390 "PushEth",
3391 self.orig_loc,
3392 self.buf.as_ptr() as usize,
3393 ))
3394 }
3395 pub fn get_pop_eth(&self) -> Result<(), ErrorContext> {
3396 let mut iter = self.clone();
3397 iter.pos = 0;
3398 for attr in iter {
3399 if let Ok(ActionAttrs::PopEth(val)) = attr {
3400 return Ok(val);
3401 }
3402 }
3403 Err(ErrorContext::new_missing(
3404 "ActionAttrs",
3405 "PopEth",
3406 self.orig_loc,
3407 self.buf.as_ptr() as usize,
3408 ))
3409 }
3410 pub fn get_ct_clear(&self) -> Result<(), ErrorContext> {
3411 let mut iter = self.clone();
3412 iter.pos = 0;
3413 for attr in iter {
3414 if let Ok(ActionAttrs::CtClear(val)) = attr {
3415 return Ok(val);
3416 }
3417 }
3418 Err(ErrorContext::new_missing(
3419 "ActionAttrs",
3420 "CtClear",
3421 self.orig_loc,
3422 self.buf.as_ptr() as usize,
3423 ))
3424 }
3425 #[doc = "Push NSH header to the packet.\n"]
3426 pub fn get_push_nsh(&self) -> Result<IterableOvsNshKeyAttrs<'a>, ErrorContext> {
3427 let mut iter = self.clone();
3428 iter.pos = 0;
3429 for attr in iter {
3430 if let Ok(ActionAttrs::PushNsh(val)) = attr {
3431 return Ok(val);
3432 }
3433 }
3434 Err(ErrorContext::new_missing(
3435 "ActionAttrs",
3436 "PushNsh",
3437 self.orig_loc,
3438 self.buf.as_ptr() as usize,
3439 ))
3440 }
3441 #[doc = "Pop the outermost NSH header off the packet.\n"]
3442 pub fn get_pop_nsh(&self) -> Result<(), ErrorContext> {
3443 let mut iter = self.clone();
3444 iter.pos = 0;
3445 for attr in iter {
3446 if let Ok(ActionAttrs::PopNsh(val)) = attr {
3447 return Ok(val);
3448 }
3449 }
3450 Err(ErrorContext::new_missing(
3451 "ActionAttrs",
3452 "PopNsh",
3453 self.orig_loc,
3454 self.buf.as_ptr() as usize,
3455 ))
3456 }
3457 #[doc = "Run packet through a meter, which may drop the packet, or modify the\npacket (e.g., change the DSCP field)\n"]
3458 pub fn get_meter(&self) -> Result<u32, ErrorContext> {
3459 let mut iter = self.clone();
3460 iter.pos = 0;
3461 for attr in iter {
3462 if let Ok(ActionAttrs::Meter(val)) = attr {
3463 return Ok(val);
3464 }
3465 }
3466 Err(ErrorContext::new_missing(
3467 "ActionAttrs",
3468 "Meter",
3469 self.orig_loc,
3470 self.buf.as_ptr() as usize,
3471 ))
3472 }
3473 #[doc = "Make a copy of the packet and execute a list of actions without\naffecting the original packet and key.\n"]
3474 pub fn get_clone(&self) -> Result<IterableActionAttrs<'a>, ErrorContext> {
3475 let mut iter = self.clone();
3476 iter.pos = 0;
3477 for attr in iter {
3478 if let Ok(ActionAttrs::Clone(val)) = attr {
3479 return Ok(val);
3480 }
3481 }
3482 Err(ErrorContext::new_missing(
3483 "ActionAttrs",
3484 "Clone",
3485 self.orig_loc,
3486 self.buf.as_ptr() as usize,
3487 ))
3488 }
3489 #[doc = "Check the packet length and execute a set of actions if greater than the\nspecified packet length, else execute another set of actions.\n"]
3490 pub fn get_check_pkt_len(&self) -> Result<IterableCheckPktLenAttrs<'a>, ErrorContext> {
3491 let mut iter = self.clone();
3492 iter.pos = 0;
3493 for attr in iter {
3494 if let Ok(ActionAttrs::CheckPktLen(val)) = attr {
3495 return Ok(val);
3496 }
3497 }
3498 Err(ErrorContext::new_missing(
3499 "ActionAttrs",
3500 "CheckPktLen",
3501 self.orig_loc,
3502 self.buf.as_ptr() as usize,
3503 ))
3504 }
3505 #[doc = "Push a new MPLS label stack entry at the start of the packet or at the\nstart of the l3 header depending on the value of l3 tunnel flag in the\ntun_flags field of this OVS_ACTION_ATTR_ADD_MPLS argument.\n"]
3506 pub fn get_add_mpls(&self) -> Result<OvsActionAddMpls, ErrorContext> {
3507 let mut iter = self.clone();
3508 iter.pos = 0;
3509 for attr in iter {
3510 if let Ok(ActionAttrs::AddMpls(val)) = attr {
3511 return Ok(val);
3512 }
3513 }
3514 Err(ErrorContext::new_missing(
3515 "ActionAttrs",
3516 "AddMpls",
3517 self.orig_loc,
3518 self.buf.as_ptr() as usize,
3519 ))
3520 }
3521 pub fn get_dec_ttl(&self) -> Result<IterableDecTtlAttrs<'a>, ErrorContext> {
3522 let mut iter = self.clone();
3523 iter.pos = 0;
3524 for attr in iter {
3525 if let Ok(ActionAttrs::DecTtl(val)) = attr {
3526 return Ok(val);
3527 }
3528 }
3529 Err(ErrorContext::new_missing(
3530 "ActionAttrs",
3531 "DecTtl",
3532 self.orig_loc,
3533 self.buf.as_ptr() as usize,
3534 ))
3535 }
3536 #[doc = "Sends a packet sample to psample for external observation.\n"]
3537 pub fn get_psample(&self) -> Result<IterablePsampleAttrs<'a>, ErrorContext> {
3538 let mut iter = self.clone();
3539 iter.pos = 0;
3540 for attr in iter {
3541 if let Ok(ActionAttrs::Psample(val)) = attr {
3542 return Ok(val);
3543 }
3544 }
3545 Err(ErrorContext::new_missing(
3546 "ActionAttrs",
3547 "Psample",
3548 self.orig_loc,
3549 self.buf.as_ptr() as usize,
3550 ))
3551 }
3552}
3553impl ActionAttrs<'_> {
3554 pub fn new<'a>(buf: &'a [u8]) -> IterableActionAttrs<'a> {
3555 IterableActionAttrs::with_loc(buf, buf.as_ptr() as usize)
3556 }
3557 fn attr_from_type(r#type: u16) -> Option<&'static str> {
3558 let res = match r#type {
3559 1u16 => "Output",
3560 2u16 => "Userspace",
3561 3u16 => "Set",
3562 4u16 => "PushVlan",
3563 5u16 => "PopVlan",
3564 6u16 => "Sample",
3565 7u16 => "Recirc",
3566 8u16 => "Hash",
3567 9u16 => "PushMpls",
3568 10u16 => "PopMpls",
3569 11u16 => "SetMasked",
3570 12u16 => "Ct",
3571 13u16 => "Trunc",
3572 14u16 => "PushEth",
3573 15u16 => "PopEth",
3574 16u16 => "CtClear",
3575 17u16 => "PushNsh",
3576 18u16 => "PopNsh",
3577 19u16 => "Meter",
3578 20u16 => "Clone",
3579 21u16 => "CheckPktLen",
3580 22u16 => "AddMpls",
3581 23u16 => "DecTtl",
3582 24u16 => "Psample",
3583 _ => return None,
3584 };
3585 Some(res)
3586 }
3587}
3588#[derive(Clone, Copy, Default)]
3589pub struct IterableActionAttrs<'a> {
3590 buf: &'a [u8],
3591 pos: usize,
3592 orig_loc: usize,
3593}
3594impl<'a> IterableActionAttrs<'a> {
3595 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
3596 Self {
3597 buf,
3598 pos: 0,
3599 orig_loc,
3600 }
3601 }
3602 pub fn get_buf(&self) -> &'a [u8] {
3603 self.buf
3604 }
3605}
3606impl<'a> Iterator for IterableActionAttrs<'a> {
3607 type Item = Result<ActionAttrs<'a>, ErrorContext>;
3608 fn next(&mut self) -> Option<Self::Item> {
3609 let mut pos;
3610 let mut r#type;
3611 loop {
3612 pos = self.pos;
3613 r#type = None;
3614 if self.buf.len() == self.pos {
3615 return None;
3616 }
3617 let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
3618 self.pos = self.buf.len();
3619 break;
3620 };
3621 r#type = Some(header.r#type);
3622 let res = match header.r#type {
3623 1u16 => ActionAttrs::Output({
3624 let res = parse_u32(next);
3625 let Some(val) = res else { break };
3626 val
3627 }),
3628 2u16 => ActionAttrs::Userspace({
3629 let res = Some(IterableUserspaceAttrs::with_loc(next, self.orig_loc));
3630 let Some(val) = res else { break };
3631 val
3632 }),
3633 3u16 => ActionAttrs::Set({
3634 let res = Some(IterableKeyAttrs::with_loc(next, self.orig_loc));
3635 let Some(val) = res else { break };
3636 val
3637 }),
3638 4u16 => ActionAttrs::PushVlan({
3639 let res = Some(OvsActionPushVlan::new_from_zeroed(next));
3640 let Some(val) = res else { break };
3641 val
3642 }),
3643 5u16 => ActionAttrs::PopVlan(()),
3644 6u16 => ActionAttrs::Sample({
3645 let res = Some(IterableSampleAttrs::with_loc(next, self.orig_loc));
3646 let Some(val) = res else { break };
3647 val
3648 }),
3649 7u16 => ActionAttrs::Recirc({
3650 let res = parse_u32(next);
3651 let Some(val) = res else { break };
3652 val
3653 }),
3654 8u16 => ActionAttrs::Hash({
3655 let res = Some(OvsActionHash::new_from_zeroed(next));
3656 let Some(val) = res else { break };
3657 val
3658 }),
3659 9u16 => ActionAttrs::PushMpls({
3660 let res = Some(OvsActionPushMpls::new_from_zeroed(next));
3661 let Some(val) = res else { break };
3662 val
3663 }),
3664 10u16 => ActionAttrs::PopMpls({
3665 let res = parse_be_u16(next);
3666 let Some(val) = res else { break };
3667 val
3668 }),
3669 11u16 => ActionAttrs::SetMasked({
3670 let res = Some(IterableKeyAttrs::with_loc(next, self.orig_loc));
3671 let Some(val) = res else { break };
3672 val
3673 }),
3674 12u16 => ActionAttrs::Ct({
3675 let res = Some(IterableCtAttrs::with_loc(next, self.orig_loc));
3676 let Some(val) = res else { break };
3677 val
3678 }),
3679 13u16 => ActionAttrs::Trunc({
3680 let res = parse_u32(next);
3681 let Some(val) = res else { break };
3682 val
3683 }),
3684 14u16 => ActionAttrs::PushEth({
3685 let res = Some(next);
3686 let Some(val) = res else { break };
3687 val
3688 }),
3689 15u16 => ActionAttrs::PopEth(()),
3690 16u16 => ActionAttrs::CtClear(()),
3691 17u16 => ActionAttrs::PushNsh({
3692 let res = Some(IterableOvsNshKeyAttrs::with_loc(next, self.orig_loc));
3693 let Some(val) = res else { break };
3694 val
3695 }),
3696 18u16 => ActionAttrs::PopNsh(()),
3697 19u16 => ActionAttrs::Meter({
3698 let res = parse_u32(next);
3699 let Some(val) = res else { break };
3700 val
3701 }),
3702 20u16 => ActionAttrs::Clone({
3703 let res = Some(IterableActionAttrs::with_loc(next, self.orig_loc));
3704 let Some(val) = res else { break };
3705 val
3706 }),
3707 21u16 => ActionAttrs::CheckPktLen({
3708 let res = Some(IterableCheckPktLenAttrs::with_loc(next, self.orig_loc));
3709 let Some(val) = res else { break };
3710 val
3711 }),
3712 22u16 => ActionAttrs::AddMpls({
3713 let res = Some(OvsActionAddMpls::new_from_zeroed(next));
3714 let Some(val) = res else { break };
3715 val
3716 }),
3717 23u16 => ActionAttrs::DecTtl({
3718 let res = Some(IterableDecTtlAttrs::with_loc(next, self.orig_loc));
3719 let Some(val) = res else { break };
3720 val
3721 }),
3722 24u16 => ActionAttrs::Psample({
3723 let res = Some(IterablePsampleAttrs::with_loc(next, self.orig_loc));
3724 let Some(val) = res else { break };
3725 val
3726 }),
3727 n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
3728 n => continue,
3729 };
3730 return Some(Ok(res));
3731 }
3732 Some(Err(ErrorContext::new(
3733 "ActionAttrs",
3734 r#type.and_then(|t| ActionAttrs::attr_from_type(t)),
3735 self.orig_loc,
3736 self.buf.as_ptr().wrapping_add(pos) as usize,
3737 )))
3738 }
3739}
3740impl<'a> std::fmt::Debug for IterableActionAttrs<'_> {
3741 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3742 let mut fmt = f.debug_struct("ActionAttrs");
3743 for attr in self.clone() {
3744 let attr = match attr {
3745 Ok(a) => a,
3746 Err(err) => {
3747 fmt.finish()?;
3748 f.write_str("Err(")?;
3749 err.fmt(f)?;
3750 return f.write_str(")");
3751 }
3752 };
3753 match attr {
3754 ActionAttrs::Output(val) => fmt.field("Output", &val),
3755 ActionAttrs::Userspace(val) => fmt.field("Userspace", &val),
3756 ActionAttrs::Set(val) => fmt.field("Set", &val),
3757 ActionAttrs::PushVlan(val) => fmt.field("PushVlan", &val),
3758 ActionAttrs::PopVlan(val) => fmt.field("PopVlan", &val),
3759 ActionAttrs::Sample(val) => fmt.field("Sample", &val),
3760 ActionAttrs::Recirc(val) => fmt.field("Recirc", &val),
3761 ActionAttrs::Hash(val) => fmt.field("Hash", &val),
3762 ActionAttrs::PushMpls(val) => fmt.field("PushMpls", &val),
3763 ActionAttrs::PopMpls(val) => fmt.field("PopMpls", &val),
3764 ActionAttrs::SetMasked(val) => fmt.field("SetMasked", &val),
3765 ActionAttrs::Ct(val) => fmt.field("Ct", &val),
3766 ActionAttrs::Trunc(val) => fmt.field("Trunc", &val),
3767 ActionAttrs::PushEth(val) => fmt.field("PushEth", &val),
3768 ActionAttrs::PopEth(val) => fmt.field("PopEth", &val),
3769 ActionAttrs::CtClear(val) => fmt.field("CtClear", &val),
3770 ActionAttrs::PushNsh(val) => fmt.field("PushNsh", &val),
3771 ActionAttrs::PopNsh(val) => fmt.field("PopNsh", &val),
3772 ActionAttrs::Meter(val) => fmt.field("Meter", &val),
3773 ActionAttrs::Clone(val) => fmt.field("Clone", &val),
3774 ActionAttrs::CheckPktLen(val) => fmt.field("CheckPktLen", &val),
3775 ActionAttrs::AddMpls(val) => fmt.field("AddMpls", &val),
3776 ActionAttrs::DecTtl(val) => fmt.field("DecTtl", &val),
3777 ActionAttrs::Psample(val) => fmt.field("Psample", &val),
3778 };
3779 }
3780 fmt.finish()
3781 }
3782}
3783impl IterableActionAttrs<'_> {
3784 pub fn lookup_attr(
3785 &self,
3786 offset: usize,
3787 missing_type: Option<u16>,
3788 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
3789 let mut stack = Vec::new();
3790 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
3791 if missing_type.is_some() && cur == offset {
3792 stack.push(("ActionAttrs", offset));
3793 return (
3794 stack,
3795 missing_type.and_then(|t| ActionAttrs::attr_from_type(t)),
3796 );
3797 }
3798 if cur > offset || cur + self.buf.len() < offset {
3799 return (stack, None);
3800 }
3801 let mut attrs = self.clone();
3802 let mut last_off = cur + attrs.pos;
3803 let mut missing = None;
3804 while let Some(attr) = attrs.next() {
3805 let Ok(attr) = attr else { break };
3806 match attr {
3807 ActionAttrs::Output(val) => {
3808 if last_off == offset {
3809 stack.push(("Output", last_off));
3810 break;
3811 }
3812 }
3813 ActionAttrs::Userspace(val) => {
3814 (stack, missing) = val.lookup_attr(offset, missing_type);
3815 if !stack.is_empty() {
3816 break;
3817 }
3818 }
3819 ActionAttrs::Set(val) => {
3820 (stack, missing) = val.lookup_attr(offset, missing_type);
3821 if !stack.is_empty() {
3822 break;
3823 }
3824 }
3825 ActionAttrs::PushVlan(val) => {
3826 if last_off == offset {
3827 stack.push(("PushVlan", last_off));
3828 break;
3829 }
3830 }
3831 ActionAttrs::PopVlan(val) => {
3832 if last_off == offset {
3833 stack.push(("PopVlan", last_off));
3834 break;
3835 }
3836 }
3837 ActionAttrs::Sample(val) => {
3838 (stack, missing) = val.lookup_attr(offset, missing_type);
3839 if !stack.is_empty() {
3840 break;
3841 }
3842 }
3843 ActionAttrs::Recirc(val) => {
3844 if last_off == offset {
3845 stack.push(("Recirc", last_off));
3846 break;
3847 }
3848 }
3849 ActionAttrs::Hash(val) => {
3850 if last_off == offset {
3851 stack.push(("Hash", last_off));
3852 break;
3853 }
3854 }
3855 ActionAttrs::PushMpls(val) => {
3856 if last_off == offset {
3857 stack.push(("PushMpls", last_off));
3858 break;
3859 }
3860 }
3861 ActionAttrs::PopMpls(val) => {
3862 if last_off == offset {
3863 stack.push(("PopMpls", last_off));
3864 break;
3865 }
3866 }
3867 ActionAttrs::SetMasked(val) => {
3868 (stack, missing) = val.lookup_attr(offset, missing_type);
3869 if !stack.is_empty() {
3870 break;
3871 }
3872 }
3873 ActionAttrs::Ct(val) => {
3874 (stack, missing) = val.lookup_attr(offset, missing_type);
3875 if !stack.is_empty() {
3876 break;
3877 }
3878 }
3879 ActionAttrs::Trunc(val) => {
3880 if last_off == offset {
3881 stack.push(("Trunc", last_off));
3882 break;
3883 }
3884 }
3885 ActionAttrs::PushEth(val) => {
3886 if last_off == offset {
3887 stack.push(("PushEth", last_off));
3888 break;
3889 }
3890 }
3891 ActionAttrs::PopEth(val) => {
3892 if last_off == offset {
3893 stack.push(("PopEth", last_off));
3894 break;
3895 }
3896 }
3897 ActionAttrs::CtClear(val) => {
3898 if last_off == offset {
3899 stack.push(("CtClear", last_off));
3900 break;
3901 }
3902 }
3903 ActionAttrs::PushNsh(val) => {
3904 (stack, missing) = val.lookup_attr(offset, missing_type);
3905 if !stack.is_empty() {
3906 break;
3907 }
3908 }
3909 ActionAttrs::PopNsh(val) => {
3910 if last_off == offset {
3911 stack.push(("PopNsh", last_off));
3912 break;
3913 }
3914 }
3915 ActionAttrs::Meter(val) => {
3916 if last_off == offset {
3917 stack.push(("Meter", last_off));
3918 break;
3919 }
3920 }
3921 ActionAttrs::Clone(val) => {
3922 (stack, missing) = val.lookup_attr(offset, missing_type);
3923 if !stack.is_empty() {
3924 break;
3925 }
3926 }
3927 ActionAttrs::CheckPktLen(val) => {
3928 (stack, missing) = val.lookup_attr(offset, missing_type);
3929 if !stack.is_empty() {
3930 break;
3931 }
3932 }
3933 ActionAttrs::AddMpls(val) => {
3934 if last_off == offset {
3935 stack.push(("AddMpls", last_off));
3936 break;
3937 }
3938 }
3939 ActionAttrs::DecTtl(val) => {
3940 (stack, missing) = val.lookup_attr(offset, missing_type);
3941 if !stack.is_empty() {
3942 break;
3943 }
3944 }
3945 ActionAttrs::Psample(val) => {
3946 (stack, missing) = val.lookup_attr(offset, missing_type);
3947 if !stack.is_empty() {
3948 break;
3949 }
3950 }
3951 _ => {}
3952 };
3953 last_off = cur + attrs.pos;
3954 }
3955 if !stack.is_empty() {
3956 stack.push(("ActionAttrs", cur));
3957 }
3958 (stack, missing)
3959 }
3960}
3961#[derive(Clone)]
3962pub enum TunnelKeyAttrs<'a> {
3963 Id(u64),
3964 Ipv4Src(u32),
3965 Ipv4Dst(u32),
3966 Tos(u8),
3967 Ttl(u8),
3968 DontFragment(()),
3969 Csum(()),
3970 Oam(()),
3971 GeneveOpts(&'a [u8]),
3972 TpSrc(u16),
3973 TpDst(u16),
3974 VxlanOpts(IterableVxlanExtAttrs<'a>),
3975 #[doc = "struct in6_addr source IPv6 address\n"]
3976 Ipv6Src(&'a [u8]),
3977 #[doc = "struct in6_addr destination IPv6 address\n"]
3978 Ipv6Dst(&'a [u8]),
3979 Pad(&'a [u8]),
3980 #[doc = "struct erspan_metadata\n"]
3981 ErspanOpts(&'a [u8]),
3982 Ipv4InfoBridge(()),
3983}
3984impl<'a> IterableTunnelKeyAttrs<'a> {
3985 pub fn get_id(&self) -> Result<u64, ErrorContext> {
3986 let mut iter = self.clone();
3987 iter.pos = 0;
3988 for attr in iter {
3989 if let Ok(TunnelKeyAttrs::Id(val)) = attr {
3990 return Ok(val);
3991 }
3992 }
3993 Err(ErrorContext::new_missing(
3994 "TunnelKeyAttrs",
3995 "Id",
3996 self.orig_loc,
3997 self.buf.as_ptr() as usize,
3998 ))
3999 }
4000 pub fn get_ipv4_src(&self) -> Result<u32, ErrorContext> {
4001 let mut iter = self.clone();
4002 iter.pos = 0;
4003 for attr in iter {
4004 if let Ok(TunnelKeyAttrs::Ipv4Src(val)) = attr {
4005 return Ok(val);
4006 }
4007 }
4008 Err(ErrorContext::new_missing(
4009 "TunnelKeyAttrs",
4010 "Ipv4Src",
4011 self.orig_loc,
4012 self.buf.as_ptr() as usize,
4013 ))
4014 }
4015 pub fn get_ipv4_dst(&self) -> Result<u32, ErrorContext> {
4016 let mut iter = self.clone();
4017 iter.pos = 0;
4018 for attr in iter {
4019 if let Ok(TunnelKeyAttrs::Ipv4Dst(val)) = attr {
4020 return Ok(val);
4021 }
4022 }
4023 Err(ErrorContext::new_missing(
4024 "TunnelKeyAttrs",
4025 "Ipv4Dst",
4026 self.orig_loc,
4027 self.buf.as_ptr() as usize,
4028 ))
4029 }
4030 pub fn get_tos(&self) -> Result<u8, ErrorContext> {
4031 let mut iter = self.clone();
4032 iter.pos = 0;
4033 for attr in iter {
4034 if let Ok(TunnelKeyAttrs::Tos(val)) = attr {
4035 return Ok(val);
4036 }
4037 }
4038 Err(ErrorContext::new_missing(
4039 "TunnelKeyAttrs",
4040 "Tos",
4041 self.orig_loc,
4042 self.buf.as_ptr() as usize,
4043 ))
4044 }
4045 pub fn get_ttl(&self) -> Result<u8, ErrorContext> {
4046 let mut iter = self.clone();
4047 iter.pos = 0;
4048 for attr in iter {
4049 if let Ok(TunnelKeyAttrs::Ttl(val)) = attr {
4050 return Ok(val);
4051 }
4052 }
4053 Err(ErrorContext::new_missing(
4054 "TunnelKeyAttrs",
4055 "Ttl",
4056 self.orig_loc,
4057 self.buf.as_ptr() as usize,
4058 ))
4059 }
4060 pub fn get_dont_fragment(&self) -> Result<(), ErrorContext> {
4061 let mut iter = self.clone();
4062 iter.pos = 0;
4063 for attr in iter {
4064 if let Ok(TunnelKeyAttrs::DontFragment(val)) = attr {
4065 return Ok(val);
4066 }
4067 }
4068 Err(ErrorContext::new_missing(
4069 "TunnelKeyAttrs",
4070 "DontFragment",
4071 self.orig_loc,
4072 self.buf.as_ptr() as usize,
4073 ))
4074 }
4075 pub fn get_csum(&self) -> Result<(), ErrorContext> {
4076 let mut iter = self.clone();
4077 iter.pos = 0;
4078 for attr in iter {
4079 if let Ok(TunnelKeyAttrs::Csum(val)) = attr {
4080 return Ok(val);
4081 }
4082 }
4083 Err(ErrorContext::new_missing(
4084 "TunnelKeyAttrs",
4085 "Csum",
4086 self.orig_loc,
4087 self.buf.as_ptr() as usize,
4088 ))
4089 }
4090 pub fn get_oam(&self) -> Result<(), ErrorContext> {
4091 let mut iter = self.clone();
4092 iter.pos = 0;
4093 for attr in iter {
4094 if let Ok(TunnelKeyAttrs::Oam(val)) = attr {
4095 return Ok(val);
4096 }
4097 }
4098 Err(ErrorContext::new_missing(
4099 "TunnelKeyAttrs",
4100 "Oam",
4101 self.orig_loc,
4102 self.buf.as_ptr() as usize,
4103 ))
4104 }
4105 pub fn get_geneve_opts(&self) -> Result<&'a [u8], ErrorContext> {
4106 let mut iter = self.clone();
4107 iter.pos = 0;
4108 for attr in iter {
4109 if let Ok(TunnelKeyAttrs::GeneveOpts(val)) = attr {
4110 return Ok(val);
4111 }
4112 }
4113 Err(ErrorContext::new_missing(
4114 "TunnelKeyAttrs",
4115 "GeneveOpts",
4116 self.orig_loc,
4117 self.buf.as_ptr() as usize,
4118 ))
4119 }
4120 pub fn get_tp_src(&self) -> Result<u16, ErrorContext> {
4121 let mut iter = self.clone();
4122 iter.pos = 0;
4123 for attr in iter {
4124 if let Ok(TunnelKeyAttrs::TpSrc(val)) = attr {
4125 return Ok(val);
4126 }
4127 }
4128 Err(ErrorContext::new_missing(
4129 "TunnelKeyAttrs",
4130 "TpSrc",
4131 self.orig_loc,
4132 self.buf.as_ptr() as usize,
4133 ))
4134 }
4135 pub fn get_tp_dst(&self) -> Result<u16, ErrorContext> {
4136 let mut iter = self.clone();
4137 iter.pos = 0;
4138 for attr in iter {
4139 if let Ok(TunnelKeyAttrs::TpDst(val)) = attr {
4140 return Ok(val);
4141 }
4142 }
4143 Err(ErrorContext::new_missing(
4144 "TunnelKeyAttrs",
4145 "TpDst",
4146 self.orig_loc,
4147 self.buf.as_ptr() as usize,
4148 ))
4149 }
4150 pub fn get_vxlan_opts(&self) -> Result<IterableVxlanExtAttrs<'a>, ErrorContext> {
4151 let mut iter = self.clone();
4152 iter.pos = 0;
4153 for attr in iter {
4154 if let Ok(TunnelKeyAttrs::VxlanOpts(val)) = attr {
4155 return Ok(val);
4156 }
4157 }
4158 Err(ErrorContext::new_missing(
4159 "TunnelKeyAttrs",
4160 "VxlanOpts",
4161 self.orig_loc,
4162 self.buf.as_ptr() as usize,
4163 ))
4164 }
4165 #[doc = "struct in6_addr source IPv6 address\n"]
4166 pub fn get_ipv6_src(&self) -> Result<&'a [u8], ErrorContext> {
4167 let mut iter = self.clone();
4168 iter.pos = 0;
4169 for attr in iter {
4170 if let Ok(TunnelKeyAttrs::Ipv6Src(val)) = attr {
4171 return Ok(val);
4172 }
4173 }
4174 Err(ErrorContext::new_missing(
4175 "TunnelKeyAttrs",
4176 "Ipv6Src",
4177 self.orig_loc,
4178 self.buf.as_ptr() as usize,
4179 ))
4180 }
4181 #[doc = "struct in6_addr destination IPv6 address\n"]
4182 pub fn get_ipv6_dst(&self) -> Result<&'a [u8], ErrorContext> {
4183 let mut iter = self.clone();
4184 iter.pos = 0;
4185 for attr in iter {
4186 if let Ok(TunnelKeyAttrs::Ipv6Dst(val)) = attr {
4187 return Ok(val);
4188 }
4189 }
4190 Err(ErrorContext::new_missing(
4191 "TunnelKeyAttrs",
4192 "Ipv6Dst",
4193 self.orig_loc,
4194 self.buf.as_ptr() as usize,
4195 ))
4196 }
4197 pub fn get_pad(&self) -> Result<&'a [u8], ErrorContext> {
4198 let mut iter = self.clone();
4199 iter.pos = 0;
4200 for attr in iter {
4201 if let Ok(TunnelKeyAttrs::Pad(val)) = attr {
4202 return Ok(val);
4203 }
4204 }
4205 Err(ErrorContext::new_missing(
4206 "TunnelKeyAttrs",
4207 "Pad",
4208 self.orig_loc,
4209 self.buf.as_ptr() as usize,
4210 ))
4211 }
4212 #[doc = "struct erspan_metadata\n"]
4213 pub fn get_erspan_opts(&self) -> Result<&'a [u8], ErrorContext> {
4214 let mut iter = self.clone();
4215 iter.pos = 0;
4216 for attr in iter {
4217 if let Ok(TunnelKeyAttrs::ErspanOpts(val)) = attr {
4218 return Ok(val);
4219 }
4220 }
4221 Err(ErrorContext::new_missing(
4222 "TunnelKeyAttrs",
4223 "ErspanOpts",
4224 self.orig_loc,
4225 self.buf.as_ptr() as usize,
4226 ))
4227 }
4228 pub fn get_ipv4_info_bridge(&self) -> Result<(), ErrorContext> {
4229 let mut iter = self.clone();
4230 iter.pos = 0;
4231 for attr in iter {
4232 if let Ok(TunnelKeyAttrs::Ipv4InfoBridge(val)) = attr {
4233 return Ok(val);
4234 }
4235 }
4236 Err(ErrorContext::new_missing(
4237 "TunnelKeyAttrs",
4238 "Ipv4InfoBridge",
4239 self.orig_loc,
4240 self.buf.as_ptr() as usize,
4241 ))
4242 }
4243}
4244impl TunnelKeyAttrs<'_> {
4245 pub fn new<'a>(buf: &'a [u8]) -> IterableTunnelKeyAttrs<'a> {
4246 IterableTunnelKeyAttrs::with_loc(buf, buf.as_ptr() as usize)
4247 }
4248 fn attr_from_type(r#type: u16) -> Option<&'static str> {
4249 let res = match r#type {
4250 0u16 => "Id",
4251 1u16 => "Ipv4Src",
4252 2u16 => "Ipv4Dst",
4253 3u16 => "Tos",
4254 4u16 => "Ttl",
4255 5u16 => "DontFragment",
4256 6u16 => "Csum",
4257 7u16 => "Oam",
4258 8u16 => "GeneveOpts",
4259 9u16 => "TpSrc",
4260 10u16 => "TpDst",
4261 11u16 => "VxlanOpts",
4262 12u16 => "Ipv6Src",
4263 13u16 => "Ipv6Dst",
4264 14u16 => "Pad",
4265 15u16 => "ErspanOpts",
4266 16u16 => "Ipv4InfoBridge",
4267 _ => return None,
4268 };
4269 Some(res)
4270 }
4271}
4272#[derive(Clone, Copy, Default)]
4273pub struct IterableTunnelKeyAttrs<'a> {
4274 buf: &'a [u8],
4275 pos: usize,
4276 orig_loc: usize,
4277}
4278impl<'a> IterableTunnelKeyAttrs<'a> {
4279 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
4280 Self {
4281 buf,
4282 pos: 0,
4283 orig_loc,
4284 }
4285 }
4286 pub fn get_buf(&self) -> &'a [u8] {
4287 self.buf
4288 }
4289}
4290impl<'a> Iterator for IterableTunnelKeyAttrs<'a> {
4291 type Item = Result<TunnelKeyAttrs<'a>, ErrorContext>;
4292 fn next(&mut self) -> Option<Self::Item> {
4293 let mut pos;
4294 let mut r#type;
4295 loop {
4296 pos = self.pos;
4297 r#type = None;
4298 if self.buf.len() == self.pos {
4299 return None;
4300 }
4301 let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
4302 self.pos = self.buf.len();
4303 break;
4304 };
4305 r#type = Some(header.r#type);
4306 let res = match header.r#type {
4307 0u16 => TunnelKeyAttrs::Id({
4308 let res = parse_be_u64(next);
4309 let Some(val) = res else { break };
4310 val
4311 }),
4312 1u16 => TunnelKeyAttrs::Ipv4Src({
4313 let res = parse_be_u32(next);
4314 let Some(val) = res else { break };
4315 val
4316 }),
4317 2u16 => TunnelKeyAttrs::Ipv4Dst({
4318 let res = parse_be_u32(next);
4319 let Some(val) = res else { break };
4320 val
4321 }),
4322 3u16 => TunnelKeyAttrs::Tos({
4323 let res = parse_u8(next);
4324 let Some(val) = res else { break };
4325 val
4326 }),
4327 4u16 => TunnelKeyAttrs::Ttl({
4328 let res = parse_u8(next);
4329 let Some(val) = res else { break };
4330 val
4331 }),
4332 5u16 => TunnelKeyAttrs::DontFragment(()),
4333 6u16 => TunnelKeyAttrs::Csum(()),
4334 7u16 => TunnelKeyAttrs::Oam(()),
4335 8u16 => TunnelKeyAttrs::GeneveOpts({
4336 let res = Some(next);
4337 let Some(val) = res else { break };
4338 val
4339 }),
4340 9u16 => TunnelKeyAttrs::TpSrc({
4341 let res = parse_be_u16(next);
4342 let Some(val) = res else { break };
4343 val
4344 }),
4345 10u16 => TunnelKeyAttrs::TpDst({
4346 let res = parse_be_u16(next);
4347 let Some(val) = res else { break };
4348 val
4349 }),
4350 11u16 => TunnelKeyAttrs::VxlanOpts({
4351 let res = Some(IterableVxlanExtAttrs::with_loc(next, self.orig_loc));
4352 let Some(val) = res else { break };
4353 val
4354 }),
4355 12u16 => TunnelKeyAttrs::Ipv6Src({
4356 let res = Some(next);
4357 let Some(val) = res else { break };
4358 val
4359 }),
4360 13u16 => TunnelKeyAttrs::Ipv6Dst({
4361 let res = Some(next);
4362 let Some(val) = res else { break };
4363 val
4364 }),
4365 14u16 => TunnelKeyAttrs::Pad({
4366 let res = Some(next);
4367 let Some(val) = res else { break };
4368 val
4369 }),
4370 15u16 => TunnelKeyAttrs::ErspanOpts({
4371 let res = Some(next);
4372 let Some(val) = res else { break };
4373 val
4374 }),
4375 16u16 => TunnelKeyAttrs::Ipv4InfoBridge(()),
4376 n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
4377 n => continue,
4378 };
4379 return Some(Ok(res));
4380 }
4381 Some(Err(ErrorContext::new(
4382 "TunnelKeyAttrs",
4383 r#type.and_then(|t| TunnelKeyAttrs::attr_from_type(t)),
4384 self.orig_loc,
4385 self.buf.as_ptr().wrapping_add(pos) as usize,
4386 )))
4387 }
4388}
4389impl<'a> std::fmt::Debug for IterableTunnelKeyAttrs<'_> {
4390 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
4391 let mut fmt = f.debug_struct("TunnelKeyAttrs");
4392 for attr in self.clone() {
4393 let attr = match attr {
4394 Ok(a) => a,
4395 Err(err) => {
4396 fmt.finish()?;
4397 f.write_str("Err(")?;
4398 err.fmt(f)?;
4399 return f.write_str(")");
4400 }
4401 };
4402 match attr {
4403 TunnelKeyAttrs::Id(val) => fmt.field("Id", &val),
4404 TunnelKeyAttrs::Ipv4Src(val) => fmt.field("Ipv4Src", &val),
4405 TunnelKeyAttrs::Ipv4Dst(val) => fmt.field("Ipv4Dst", &val),
4406 TunnelKeyAttrs::Tos(val) => fmt.field("Tos", &val),
4407 TunnelKeyAttrs::Ttl(val) => fmt.field("Ttl", &val),
4408 TunnelKeyAttrs::DontFragment(val) => fmt.field("DontFragment", &val),
4409 TunnelKeyAttrs::Csum(val) => fmt.field("Csum", &val),
4410 TunnelKeyAttrs::Oam(val) => fmt.field("Oam", &val),
4411 TunnelKeyAttrs::GeneveOpts(val) => fmt.field("GeneveOpts", &val),
4412 TunnelKeyAttrs::TpSrc(val) => fmt.field("TpSrc", &val),
4413 TunnelKeyAttrs::TpDst(val) => fmt.field("TpDst", &val),
4414 TunnelKeyAttrs::VxlanOpts(val) => fmt.field("VxlanOpts", &val),
4415 TunnelKeyAttrs::Ipv6Src(val) => fmt.field("Ipv6Src", &val),
4416 TunnelKeyAttrs::Ipv6Dst(val) => fmt.field("Ipv6Dst", &val),
4417 TunnelKeyAttrs::Pad(val) => fmt.field("Pad", &val),
4418 TunnelKeyAttrs::ErspanOpts(val) => fmt.field("ErspanOpts", &val),
4419 TunnelKeyAttrs::Ipv4InfoBridge(val) => fmt.field("Ipv4InfoBridge", &val),
4420 };
4421 }
4422 fmt.finish()
4423 }
4424}
4425impl IterableTunnelKeyAttrs<'_> {
4426 pub fn lookup_attr(
4427 &self,
4428 offset: usize,
4429 missing_type: Option<u16>,
4430 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
4431 let mut stack = Vec::new();
4432 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
4433 if missing_type.is_some() && cur == offset {
4434 stack.push(("TunnelKeyAttrs", offset));
4435 return (
4436 stack,
4437 missing_type.and_then(|t| TunnelKeyAttrs::attr_from_type(t)),
4438 );
4439 }
4440 if cur > offset || cur + self.buf.len() < offset {
4441 return (stack, None);
4442 }
4443 let mut attrs = self.clone();
4444 let mut last_off = cur + attrs.pos;
4445 let mut missing = None;
4446 while let Some(attr) = attrs.next() {
4447 let Ok(attr) = attr else { break };
4448 match attr {
4449 TunnelKeyAttrs::Id(val) => {
4450 if last_off == offset {
4451 stack.push(("Id", last_off));
4452 break;
4453 }
4454 }
4455 TunnelKeyAttrs::Ipv4Src(val) => {
4456 if last_off == offset {
4457 stack.push(("Ipv4Src", last_off));
4458 break;
4459 }
4460 }
4461 TunnelKeyAttrs::Ipv4Dst(val) => {
4462 if last_off == offset {
4463 stack.push(("Ipv4Dst", last_off));
4464 break;
4465 }
4466 }
4467 TunnelKeyAttrs::Tos(val) => {
4468 if last_off == offset {
4469 stack.push(("Tos", last_off));
4470 break;
4471 }
4472 }
4473 TunnelKeyAttrs::Ttl(val) => {
4474 if last_off == offset {
4475 stack.push(("Ttl", last_off));
4476 break;
4477 }
4478 }
4479 TunnelKeyAttrs::DontFragment(val) => {
4480 if last_off == offset {
4481 stack.push(("DontFragment", last_off));
4482 break;
4483 }
4484 }
4485 TunnelKeyAttrs::Csum(val) => {
4486 if last_off == offset {
4487 stack.push(("Csum", last_off));
4488 break;
4489 }
4490 }
4491 TunnelKeyAttrs::Oam(val) => {
4492 if last_off == offset {
4493 stack.push(("Oam", last_off));
4494 break;
4495 }
4496 }
4497 TunnelKeyAttrs::GeneveOpts(val) => {
4498 if last_off == offset {
4499 stack.push(("GeneveOpts", last_off));
4500 break;
4501 }
4502 }
4503 TunnelKeyAttrs::TpSrc(val) => {
4504 if last_off == offset {
4505 stack.push(("TpSrc", last_off));
4506 break;
4507 }
4508 }
4509 TunnelKeyAttrs::TpDst(val) => {
4510 if last_off == offset {
4511 stack.push(("TpDst", last_off));
4512 break;
4513 }
4514 }
4515 TunnelKeyAttrs::VxlanOpts(val) => {
4516 (stack, missing) = val.lookup_attr(offset, missing_type);
4517 if !stack.is_empty() {
4518 break;
4519 }
4520 }
4521 TunnelKeyAttrs::Ipv6Src(val) => {
4522 if last_off == offset {
4523 stack.push(("Ipv6Src", last_off));
4524 break;
4525 }
4526 }
4527 TunnelKeyAttrs::Ipv6Dst(val) => {
4528 if last_off == offset {
4529 stack.push(("Ipv6Dst", last_off));
4530 break;
4531 }
4532 }
4533 TunnelKeyAttrs::Pad(val) => {
4534 if last_off == offset {
4535 stack.push(("Pad", last_off));
4536 break;
4537 }
4538 }
4539 TunnelKeyAttrs::ErspanOpts(val) => {
4540 if last_off == offset {
4541 stack.push(("ErspanOpts", last_off));
4542 break;
4543 }
4544 }
4545 TunnelKeyAttrs::Ipv4InfoBridge(val) => {
4546 if last_off == offset {
4547 stack.push(("Ipv4InfoBridge", last_off));
4548 break;
4549 }
4550 }
4551 _ => {}
4552 };
4553 last_off = cur + attrs.pos;
4554 }
4555 if !stack.is_empty() {
4556 stack.push(("TunnelKeyAttrs", cur));
4557 }
4558 (stack, missing)
4559 }
4560}
4561#[derive(Clone)]
4562pub enum CheckPktLenAttrs<'a> {
4563 PktLen(u16),
4564 ActionsIfGreater(IterableActionAttrs<'a>),
4565 ActionsIfLessEqual(IterableActionAttrs<'a>),
4566}
4567impl<'a> IterableCheckPktLenAttrs<'a> {
4568 pub fn get_pkt_len(&self) -> Result<u16, ErrorContext> {
4569 let mut iter = self.clone();
4570 iter.pos = 0;
4571 for attr in iter {
4572 if let Ok(CheckPktLenAttrs::PktLen(val)) = attr {
4573 return Ok(val);
4574 }
4575 }
4576 Err(ErrorContext::new_missing(
4577 "CheckPktLenAttrs",
4578 "PktLen",
4579 self.orig_loc,
4580 self.buf.as_ptr() as usize,
4581 ))
4582 }
4583 pub fn get_actions_if_greater(&self) -> Result<IterableActionAttrs<'a>, ErrorContext> {
4584 let mut iter = self.clone();
4585 iter.pos = 0;
4586 for attr in iter {
4587 if let Ok(CheckPktLenAttrs::ActionsIfGreater(val)) = attr {
4588 return Ok(val);
4589 }
4590 }
4591 Err(ErrorContext::new_missing(
4592 "CheckPktLenAttrs",
4593 "ActionsIfGreater",
4594 self.orig_loc,
4595 self.buf.as_ptr() as usize,
4596 ))
4597 }
4598 pub fn get_actions_if_less_equal(&self) -> Result<IterableActionAttrs<'a>, ErrorContext> {
4599 let mut iter = self.clone();
4600 iter.pos = 0;
4601 for attr in iter {
4602 if let Ok(CheckPktLenAttrs::ActionsIfLessEqual(val)) = attr {
4603 return Ok(val);
4604 }
4605 }
4606 Err(ErrorContext::new_missing(
4607 "CheckPktLenAttrs",
4608 "ActionsIfLessEqual",
4609 self.orig_loc,
4610 self.buf.as_ptr() as usize,
4611 ))
4612 }
4613}
4614impl CheckPktLenAttrs<'_> {
4615 pub fn new<'a>(buf: &'a [u8]) -> IterableCheckPktLenAttrs<'a> {
4616 IterableCheckPktLenAttrs::with_loc(buf, buf.as_ptr() as usize)
4617 }
4618 fn attr_from_type(r#type: u16) -> Option<&'static str> {
4619 let res = match r#type {
4620 1u16 => "PktLen",
4621 2u16 => "ActionsIfGreater",
4622 3u16 => "ActionsIfLessEqual",
4623 _ => return None,
4624 };
4625 Some(res)
4626 }
4627}
4628#[derive(Clone, Copy, Default)]
4629pub struct IterableCheckPktLenAttrs<'a> {
4630 buf: &'a [u8],
4631 pos: usize,
4632 orig_loc: usize,
4633}
4634impl<'a> IterableCheckPktLenAttrs<'a> {
4635 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
4636 Self {
4637 buf,
4638 pos: 0,
4639 orig_loc,
4640 }
4641 }
4642 pub fn get_buf(&self) -> &'a [u8] {
4643 self.buf
4644 }
4645}
4646impl<'a> Iterator for IterableCheckPktLenAttrs<'a> {
4647 type Item = Result<CheckPktLenAttrs<'a>, ErrorContext>;
4648 fn next(&mut self) -> Option<Self::Item> {
4649 let mut pos;
4650 let mut r#type;
4651 loop {
4652 pos = self.pos;
4653 r#type = None;
4654 if self.buf.len() == self.pos {
4655 return None;
4656 }
4657 let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
4658 self.pos = self.buf.len();
4659 break;
4660 };
4661 r#type = Some(header.r#type);
4662 let res = match header.r#type {
4663 1u16 => CheckPktLenAttrs::PktLen({
4664 let res = parse_u16(next);
4665 let Some(val) = res else { break };
4666 val
4667 }),
4668 2u16 => CheckPktLenAttrs::ActionsIfGreater({
4669 let res = Some(IterableActionAttrs::with_loc(next, self.orig_loc));
4670 let Some(val) = res else { break };
4671 val
4672 }),
4673 3u16 => CheckPktLenAttrs::ActionsIfLessEqual({
4674 let res = Some(IterableActionAttrs::with_loc(next, self.orig_loc));
4675 let Some(val) = res else { break };
4676 val
4677 }),
4678 n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
4679 n => continue,
4680 };
4681 return Some(Ok(res));
4682 }
4683 Some(Err(ErrorContext::new(
4684 "CheckPktLenAttrs",
4685 r#type.and_then(|t| CheckPktLenAttrs::attr_from_type(t)),
4686 self.orig_loc,
4687 self.buf.as_ptr().wrapping_add(pos) as usize,
4688 )))
4689 }
4690}
4691impl<'a> std::fmt::Debug for IterableCheckPktLenAttrs<'_> {
4692 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
4693 let mut fmt = f.debug_struct("CheckPktLenAttrs");
4694 for attr in self.clone() {
4695 let attr = match attr {
4696 Ok(a) => a,
4697 Err(err) => {
4698 fmt.finish()?;
4699 f.write_str("Err(")?;
4700 err.fmt(f)?;
4701 return f.write_str(")");
4702 }
4703 };
4704 match attr {
4705 CheckPktLenAttrs::PktLen(val) => fmt.field("PktLen", &val),
4706 CheckPktLenAttrs::ActionsIfGreater(val) => fmt.field("ActionsIfGreater", &val),
4707 CheckPktLenAttrs::ActionsIfLessEqual(val) => fmt.field("ActionsIfLessEqual", &val),
4708 };
4709 }
4710 fmt.finish()
4711 }
4712}
4713impl IterableCheckPktLenAttrs<'_> {
4714 pub fn lookup_attr(
4715 &self,
4716 offset: usize,
4717 missing_type: Option<u16>,
4718 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
4719 let mut stack = Vec::new();
4720 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
4721 if missing_type.is_some() && cur == offset {
4722 stack.push(("CheckPktLenAttrs", offset));
4723 return (
4724 stack,
4725 missing_type.and_then(|t| CheckPktLenAttrs::attr_from_type(t)),
4726 );
4727 }
4728 if cur > offset || cur + self.buf.len() < offset {
4729 return (stack, None);
4730 }
4731 let mut attrs = self.clone();
4732 let mut last_off = cur + attrs.pos;
4733 let mut missing = None;
4734 while let Some(attr) = attrs.next() {
4735 let Ok(attr) = attr else { break };
4736 match attr {
4737 CheckPktLenAttrs::PktLen(val) => {
4738 if last_off == offset {
4739 stack.push(("PktLen", last_off));
4740 break;
4741 }
4742 }
4743 CheckPktLenAttrs::ActionsIfGreater(val) => {
4744 (stack, missing) = val.lookup_attr(offset, missing_type);
4745 if !stack.is_empty() {
4746 break;
4747 }
4748 }
4749 CheckPktLenAttrs::ActionsIfLessEqual(val) => {
4750 (stack, missing) = val.lookup_attr(offset, missing_type);
4751 if !stack.is_empty() {
4752 break;
4753 }
4754 }
4755 _ => {}
4756 };
4757 last_off = cur + attrs.pos;
4758 }
4759 if !stack.is_empty() {
4760 stack.push(("CheckPktLenAttrs", cur));
4761 }
4762 (stack, missing)
4763 }
4764}
4765#[derive(Clone)]
4766pub enum SampleAttrs<'a> {
4767 Probability(u32),
4768 Actions(IterableActionAttrs<'a>),
4769}
4770impl<'a> IterableSampleAttrs<'a> {
4771 pub fn get_probability(&self) -> Result<u32, ErrorContext> {
4772 let mut iter = self.clone();
4773 iter.pos = 0;
4774 for attr in iter {
4775 if let Ok(SampleAttrs::Probability(val)) = attr {
4776 return Ok(val);
4777 }
4778 }
4779 Err(ErrorContext::new_missing(
4780 "SampleAttrs",
4781 "Probability",
4782 self.orig_loc,
4783 self.buf.as_ptr() as usize,
4784 ))
4785 }
4786 pub fn get_actions(&self) -> Result<IterableActionAttrs<'a>, ErrorContext> {
4787 let mut iter = self.clone();
4788 iter.pos = 0;
4789 for attr in iter {
4790 if let Ok(SampleAttrs::Actions(val)) = attr {
4791 return Ok(val);
4792 }
4793 }
4794 Err(ErrorContext::new_missing(
4795 "SampleAttrs",
4796 "Actions",
4797 self.orig_loc,
4798 self.buf.as_ptr() as usize,
4799 ))
4800 }
4801}
4802impl SampleAttrs<'_> {
4803 pub fn new<'a>(buf: &'a [u8]) -> IterableSampleAttrs<'a> {
4804 IterableSampleAttrs::with_loc(buf, buf.as_ptr() as usize)
4805 }
4806 fn attr_from_type(r#type: u16) -> Option<&'static str> {
4807 let res = match r#type {
4808 1u16 => "Probability",
4809 2u16 => "Actions",
4810 _ => return None,
4811 };
4812 Some(res)
4813 }
4814}
4815#[derive(Clone, Copy, Default)]
4816pub struct IterableSampleAttrs<'a> {
4817 buf: &'a [u8],
4818 pos: usize,
4819 orig_loc: usize,
4820}
4821impl<'a> IterableSampleAttrs<'a> {
4822 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
4823 Self {
4824 buf,
4825 pos: 0,
4826 orig_loc,
4827 }
4828 }
4829 pub fn get_buf(&self) -> &'a [u8] {
4830 self.buf
4831 }
4832}
4833impl<'a> Iterator for IterableSampleAttrs<'a> {
4834 type Item = Result<SampleAttrs<'a>, ErrorContext>;
4835 fn next(&mut self) -> Option<Self::Item> {
4836 let mut pos;
4837 let mut r#type;
4838 loop {
4839 pos = self.pos;
4840 r#type = None;
4841 if self.buf.len() == self.pos {
4842 return None;
4843 }
4844 let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
4845 self.pos = self.buf.len();
4846 break;
4847 };
4848 r#type = Some(header.r#type);
4849 let res = match header.r#type {
4850 1u16 => SampleAttrs::Probability({
4851 let res = parse_u32(next);
4852 let Some(val) = res else { break };
4853 val
4854 }),
4855 2u16 => SampleAttrs::Actions({
4856 let res = Some(IterableActionAttrs::with_loc(next, self.orig_loc));
4857 let Some(val) = res else { break };
4858 val
4859 }),
4860 n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
4861 n => continue,
4862 };
4863 return Some(Ok(res));
4864 }
4865 Some(Err(ErrorContext::new(
4866 "SampleAttrs",
4867 r#type.and_then(|t| SampleAttrs::attr_from_type(t)),
4868 self.orig_loc,
4869 self.buf.as_ptr().wrapping_add(pos) as usize,
4870 )))
4871 }
4872}
4873impl<'a> std::fmt::Debug for IterableSampleAttrs<'_> {
4874 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
4875 let mut fmt = f.debug_struct("SampleAttrs");
4876 for attr in self.clone() {
4877 let attr = match attr {
4878 Ok(a) => a,
4879 Err(err) => {
4880 fmt.finish()?;
4881 f.write_str("Err(")?;
4882 err.fmt(f)?;
4883 return f.write_str(")");
4884 }
4885 };
4886 match attr {
4887 SampleAttrs::Probability(val) => fmt.field("Probability", &val),
4888 SampleAttrs::Actions(val) => fmt.field("Actions", &val),
4889 };
4890 }
4891 fmt.finish()
4892 }
4893}
4894impl IterableSampleAttrs<'_> {
4895 pub fn lookup_attr(
4896 &self,
4897 offset: usize,
4898 missing_type: Option<u16>,
4899 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
4900 let mut stack = Vec::new();
4901 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
4902 if missing_type.is_some() && cur == offset {
4903 stack.push(("SampleAttrs", offset));
4904 return (
4905 stack,
4906 missing_type.and_then(|t| SampleAttrs::attr_from_type(t)),
4907 );
4908 }
4909 if cur > offset || cur + self.buf.len() < offset {
4910 return (stack, None);
4911 }
4912 let mut attrs = self.clone();
4913 let mut last_off = cur + attrs.pos;
4914 let mut missing = None;
4915 while let Some(attr) = attrs.next() {
4916 let Ok(attr) = attr else { break };
4917 match attr {
4918 SampleAttrs::Probability(val) => {
4919 if last_off == offset {
4920 stack.push(("Probability", last_off));
4921 break;
4922 }
4923 }
4924 SampleAttrs::Actions(val) => {
4925 (stack, missing) = val.lookup_attr(offset, missing_type);
4926 if !stack.is_empty() {
4927 break;
4928 }
4929 }
4930 _ => {}
4931 };
4932 last_off = cur + attrs.pos;
4933 }
4934 if !stack.is_empty() {
4935 stack.push(("SampleAttrs", cur));
4936 }
4937 (stack, missing)
4938 }
4939}
4940#[derive(Clone)]
4941pub enum UserspaceAttrs<'a> {
4942 Pid(u32),
4943 Userdata(&'a [u8]),
4944 EgressTunPort(u32),
4945 Actions(()),
4946}
4947impl<'a> IterableUserspaceAttrs<'a> {
4948 pub fn get_pid(&self) -> Result<u32, ErrorContext> {
4949 let mut iter = self.clone();
4950 iter.pos = 0;
4951 for attr in iter {
4952 if let Ok(UserspaceAttrs::Pid(val)) = attr {
4953 return Ok(val);
4954 }
4955 }
4956 Err(ErrorContext::new_missing(
4957 "UserspaceAttrs",
4958 "Pid",
4959 self.orig_loc,
4960 self.buf.as_ptr() as usize,
4961 ))
4962 }
4963 pub fn get_userdata(&self) -> Result<&'a [u8], ErrorContext> {
4964 let mut iter = self.clone();
4965 iter.pos = 0;
4966 for attr in iter {
4967 if let Ok(UserspaceAttrs::Userdata(val)) = attr {
4968 return Ok(val);
4969 }
4970 }
4971 Err(ErrorContext::new_missing(
4972 "UserspaceAttrs",
4973 "Userdata",
4974 self.orig_loc,
4975 self.buf.as_ptr() as usize,
4976 ))
4977 }
4978 pub fn get_egress_tun_port(&self) -> Result<u32, ErrorContext> {
4979 let mut iter = self.clone();
4980 iter.pos = 0;
4981 for attr in iter {
4982 if let Ok(UserspaceAttrs::EgressTunPort(val)) = attr {
4983 return Ok(val);
4984 }
4985 }
4986 Err(ErrorContext::new_missing(
4987 "UserspaceAttrs",
4988 "EgressTunPort",
4989 self.orig_loc,
4990 self.buf.as_ptr() as usize,
4991 ))
4992 }
4993 pub fn get_actions(&self) -> Result<(), ErrorContext> {
4994 let mut iter = self.clone();
4995 iter.pos = 0;
4996 for attr in iter {
4997 if let Ok(UserspaceAttrs::Actions(val)) = attr {
4998 return Ok(val);
4999 }
5000 }
5001 Err(ErrorContext::new_missing(
5002 "UserspaceAttrs",
5003 "Actions",
5004 self.orig_loc,
5005 self.buf.as_ptr() as usize,
5006 ))
5007 }
5008}
5009impl UserspaceAttrs<'_> {
5010 pub fn new<'a>(buf: &'a [u8]) -> IterableUserspaceAttrs<'a> {
5011 IterableUserspaceAttrs::with_loc(buf, buf.as_ptr() as usize)
5012 }
5013 fn attr_from_type(r#type: u16) -> Option<&'static str> {
5014 let res = match r#type {
5015 1u16 => "Pid",
5016 2u16 => "Userdata",
5017 3u16 => "EgressTunPort",
5018 4u16 => "Actions",
5019 _ => return None,
5020 };
5021 Some(res)
5022 }
5023}
5024#[derive(Clone, Copy, Default)]
5025pub struct IterableUserspaceAttrs<'a> {
5026 buf: &'a [u8],
5027 pos: usize,
5028 orig_loc: usize,
5029}
5030impl<'a> IterableUserspaceAttrs<'a> {
5031 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
5032 Self {
5033 buf,
5034 pos: 0,
5035 orig_loc,
5036 }
5037 }
5038 pub fn get_buf(&self) -> &'a [u8] {
5039 self.buf
5040 }
5041}
5042impl<'a> Iterator for IterableUserspaceAttrs<'a> {
5043 type Item = Result<UserspaceAttrs<'a>, ErrorContext>;
5044 fn next(&mut self) -> Option<Self::Item> {
5045 let mut pos;
5046 let mut r#type;
5047 loop {
5048 pos = self.pos;
5049 r#type = None;
5050 if self.buf.len() == self.pos {
5051 return None;
5052 }
5053 let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
5054 self.pos = self.buf.len();
5055 break;
5056 };
5057 r#type = Some(header.r#type);
5058 let res = match header.r#type {
5059 1u16 => UserspaceAttrs::Pid({
5060 let res = parse_u32(next);
5061 let Some(val) = res else { break };
5062 val
5063 }),
5064 2u16 => UserspaceAttrs::Userdata({
5065 let res = Some(next);
5066 let Some(val) = res else { break };
5067 val
5068 }),
5069 3u16 => UserspaceAttrs::EgressTunPort({
5070 let res = parse_u32(next);
5071 let Some(val) = res else { break };
5072 val
5073 }),
5074 4u16 => UserspaceAttrs::Actions(()),
5075 n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
5076 n => continue,
5077 };
5078 return Some(Ok(res));
5079 }
5080 Some(Err(ErrorContext::new(
5081 "UserspaceAttrs",
5082 r#type.and_then(|t| UserspaceAttrs::attr_from_type(t)),
5083 self.orig_loc,
5084 self.buf.as_ptr().wrapping_add(pos) as usize,
5085 )))
5086 }
5087}
5088impl<'a> std::fmt::Debug for IterableUserspaceAttrs<'_> {
5089 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
5090 let mut fmt = f.debug_struct("UserspaceAttrs");
5091 for attr in self.clone() {
5092 let attr = match attr {
5093 Ok(a) => a,
5094 Err(err) => {
5095 fmt.finish()?;
5096 f.write_str("Err(")?;
5097 err.fmt(f)?;
5098 return f.write_str(")");
5099 }
5100 };
5101 match attr {
5102 UserspaceAttrs::Pid(val) => fmt.field("Pid", &val),
5103 UserspaceAttrs::Userdata(val) => fmt.field("Userdata", &val),
5104 UserspaceAttrs::EgressTunPort(val) => fmt.field("EgressTunPort", &val),
5105 UserspaceAttrs::Actions(val) => fmt.field("Actions", &val),
5106 };
5107 }
5108 fmt.finish()
5109 }
5110}
5111impl IterableUserspaceAttrs<'_> {
5112 pub fn lookup_attr(
5113 &self,
5114 offset: usize,
5115 missing_type: Option<u16>,
5116 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
5117 let mut stack = Vec::new();
5118 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
5119 if missing_type.is_some() && cur == offset {
5120 stack.push(("UserspaceAttrs", offset));
5121 return (
5122 stack,
5123 missing_type.and_then(|t| UserspaceAttrs::attr_from_type(t)),
5124 );
5125 }
5126 if cur > offset || cur + self.buf.len() < offset {
5127 return (stack, None);
5128 }
5129 let mut attrs = self.clone();
5130 let mut last_off = cur + attrs.pos;
5131 while let Some(attr) = attrs.next() {
5132 let Ok(attr) = attr else { break };
5133 match attr {
5134 UserspaceAttrs::Pid(val) => {
5135 if last_off == offset {
5136 stack.push(("Pid", last_off));
5137 break;
5138 }
5139 }
5140 UserspaceAttrs::Userdata(val) => {
5141 if last_off == offset {
5142 stack.push(("Userdata", last_off));
5143 break;
5144 }
5145 }
5146 UserspaceAttrs::EgressTunPort(val) => {
5147 if last_off == offset {
5148 stack.push(("EgressTunPort", last_off));
5149 break;
5150 }
5151 }
5152 UserspaceAttrs::Actions(val) => {
5153 if last_off == offset {
5154 stack.push(("Actions", last_off));
5155 break;
5156 }
5157 }
5158 _ => {}
5159 };
5160 last_off = cur + attrs.pos;
5161 }
5162 if !stack.is_empty() {
5163 stack.push(("UserspaceAttrs", cur));
5164 }
5165 (stack, None)
5166 }
5167}
5168#[derive(Clone)]
5169pub enum OvsNshKeyAttrs<'a> {
5170 Base(&'a [u8]),
5171 Md1(&'a [u8]),
5172 Md2(&'a [u8]),
5173}
5174impl<'a> IterableOvsNshKeyAttrs<'a> {
5175 pub fn get_base(&self) -> Result<&'a [u8], ErrorContext> {
5176 let mut iter = self.clone();
5177 iter.pos = 0;
5178 for attr in iter {
5179 if let Ok(OvsNshKeyAttrs::Base(val)) = attr {
5180 return Ok(val);
5181 }
5182 }
5183 Err(ErrorContext::new_missing(
5184 "OvsNshKeyAttrs",
5185 "Base",
5186 self.orig_loc,
5187 self.buf.as_ptr() as usize,
5188 ))
5189 }
5190 pub fn get_md1(&self) -> Result<&'a [u8], ErrorContext> {
5191 let mut iter = self.clone();
5192 iter.pos = 0;
5193 for attr in iter {
5194 if let Ok(OvsNshKeyAttrs::Md1(val)) = attr {
5195 return Ok(val);
5196 }
5197 }
5198 Err(ErrorContext::new_missing(
5199 "OvsNshKeyAttrs",
5200 "Md1",
5201 self.orig_loc,
5202 self.buf.as_ptr() as usize,
5203 ))
5204 }
5205 pub fn get_md2(&self) -> Result<&'a [u8], ErrorContext> {
5206 let mut iter = self.clone();
5207 iter.pos = 0;
5208 for attr in iter {
5209 if let Ok(OvsNshKeyAttrs::Md2(val)) = attr {
5210 return Ok(val);
5211 }
5212 }
5213 Err(ErrorContext::new_missing(
5214 "OvsNshKeyAttrs",
5215 "Md2",
5216 self.orig_loc,
5217 self.buf.as_ptr() as usize,
5218 ))
5219 }
5220}
5221impl OvsNshKeyAttrs<'_> {
5222 pub fn new<'a>(buf: &'a [u8]) -> IterableOvsNshKeyAttrs<'a> {
5223 IterableOvsNshKeyAttrs::with_loc(buf, buf.as_ptr() as usize)
5224 }
5225 fn attr_from_type(r#type: u16) -> Option<&'static str> {
5226 let res = match r#type {
5227 1u16 => "Base",
5228 2u16 => "Md1",
5229 3u16 => "Md2",
5230 _ => return None,
5231 };
5232 Some(res)
5233 }
5234}
5235#[derive(Clone, Copy, Default)]
5236pub struct IterableOvsNshKeyAttrs<'a> {
5237 buf: &'a [u8],
5238 pos: usize,
5239 orig_loc: usize,
5240}
5241impl<'a> IterableOvsNshKeyAttrs<'a> {
5242 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
5243 Self {
5244 buf,
5245 pos: 0,
5246 orig_loc,
5247 }
5248 }
5249 pub fn get_buf(&self) -> &'a [u8] {
5250 self.buf
5251 }
5252}
5253impl<'a> Iterator for IterableOvsNshKeyAttrs<'a> {
5254 type Item = Result<OvsNshKeyAttrs<'a>, ErrorContext>;
5255 fn next(&mut self) -> Option<Self::Item> {
5256 let mut pos;
5257 let mut r#type;
5258 loop {
5259 pos = self.pos;
5260 r#type = None;
5261 if self.buf.len() == self.pos {
5262 return None;
5263 }
5264 let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
5265 self.pos = self.buf.len();
5266 break;
5267 };
5268 r#type = Some(header.r#type);
5269 let res = match header.r#type {
5270 1u16 => OvsNshKeyAttrs::Base({
5271 let res = Some(next);
5272 let Some(val) = res else { break };
5273 val
5274 }),
5275 2u16 => OvsNshKeyAttrs::Md1({
5276 let res = Some(next);
5277 let Some(val) = res else { break };
5278 val
5279 }),
5280 3u16 => OvsNshKeyAttrs::Md2({
5281 let res = Some(next);
5282 let Some(val) = res else { break };
5283 val
5284 }),
5285 n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
5286 n => continue,
5287 };
5288 return Some(Ok(res));
5289 }
5290 Some(Err(ErrorContext::new(
5291 "OvsNshKeyAttrs",
5292 r#type.and_then(|t| OvsNshKeyAttrs::attr_from_type(t)),
5293 self.orig_loc,
5294 self.buf.as_ptr().wrapping_add(pos) as usize,
5295 )))
5296 }
5297}
5298impl<'a> std::fmt::Debug for IterableOvsNshKeyAttrs<'_> {
5299 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
5300 let mut fmt = f.debug_struct("OvsNshKeyAttrs");
5301 for attr in self.clone() {
5302 let attr = match attr {
5303 Ok(a) => a,
5304 Err(err) => {
5305 fmt.finish()?;
5306 f.write_str("Err(")?;
5307 err.fmt(f)?;
5308 return f.write_str(")");
5309 }
5310 };
5311 match attr {
5312 OvsNshKeyAttrs::Base(val) => fmt.field("Base", &val),
5313 OvsNshKeyAttrs::Md1(val) => fmt.field("Md1", &val),
5314 OvsNshKeyAttrs::Md2(val) => fmt.field("Md2", &val),
5315 };
5316 }
5317 fmt.finish()
5318 }
5319}
5320impl IterableOvsNshKeyAttrs<'_> {
5321 pub fn lookup_attr(
5322 &self,
5323 offset: usize,
5324 missing_type: Option<u16>,
5325 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
5326 let mut stack = Vec::new();
5327 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
5328 if missing_type.is_some() && cur == offset {
5329 stack.push(("OvsNshKeyAttrs", offset));
5330 return (
5331 stack,
5332 missing_type.and_then(|t| OvsNshKeyAttrs::attr_from_type(t)),
5333 );
5334 }
5335 if cur > offset || cur + self.buf.len() < offset {
5336 return (stack, None);
5337 }
5338 let mut attrs = self.clone();
5339 let mut last_off = cur + attrs.pos;
5340 while let Some(attr) = attrs.next() {
5341 let Ok(attr) = attr else { break };
5342 match attr {
5343 OvsNshKeyAttrs::Base(val) => {
5344 if last_off == offset {
5345 stack.push(("Base", last_off));
5346 break;
5347 }
5348 }
5349 OvsNshKeyAttrs::Md1(val) => {
5350 if last_off == offset {
5351 stack.push(("Md1", last_off));
5352 break;
5353 }
5354 }
5355 OvsNshKeyAttrs::Md2(val) => {
5356 if last_off == offset {
5357 stack.push(("Md2", last_off));
5358 break;
5359 }
5360 }
5361 _ => {}
5362 };
5363 last_off = cur + attrs.pos;
5364 }
5365 if !stack.is_empty() {
5366 stack.push(("OvsNshKeyAttrs", cur));
5367 }
5368 (stack, None)
5369 }
5370}
5371#[derive(Clone)]
5372pub enum CtAttrs<'a> {
5373 Commit(()),
5374 Zone(u16),
5375 Mark(&'a [u8]),
5376 Labels(&'a [u8]),
5377 Helper(&'a CStr),
5378 Nat(IterableNatAttrs<'a>),
5379 ForceCommit(()),
5380 Eventmask(u32),
5381 Timeout(&'a CStr),
5382}
5383impl<'a> IterableCtAttrs<'a> {
5384 pub fn get_commit(&self) -> Result<(), ErrorContext> {
5385 let mut iter = self.clone();
5386 iter.pos = 0;
5387 for attr in iter {
5388 if let Ok(CtAttrs::Commit(val)) = attr {
5389 return Ok(val);
5390 }
5391 }
5392 Err(ErrorContext::new_missing(
5393 "CtAttrs",
5394 "Commit",
5395 self.orig_loc,
5396 self.buf.as_ptr() as usize,
5397 ))
5398 }
5399 pub fn get_zone(&self) -> Result<u16, ErrorContext> {
5400 let mut iter = self.clone();
5401 iter.pos = 0;
5402 for attr in iter {
5403 if let Ok(CtAttrs::Zone(val)) = attr {
5404 return Ok(val);
5405 }
5406 }
5407 Err(ErrorContext::new_missing(
5408 "CtAttrs",
5409 "Zone",
5410 self.orig_loc,
5411 self.buf.as_ptr() as usize,
5412 ))
5413 }
5414 pub fn get_mark(&self) -> Result<&'a [u8], ErrorContext> {
5415 let mut iter = self.clone();
5416 iter.pos = 0;
5417 for attr in iter {
5418 if let Ok(CtAttrs::Mark(val)) = attr {
5419 return Ok(val);
5420 }
5421 }
5422 Err(ErrorContext::new_missing(
5423 "CtAttrs",
5424 "Mark",
5425 self.orig_loc,
5426 self.buf.as_ptr() as usize,
5427 ))
5428 }
5429 pub fn get_labels(&self) -> Result<&'a [u8], ErrorContext> {
5430 let mut iter = self.clone();
5431 iter.pos = 0;
5432 for attr in iter {
5433 if let Ok(CtAttrs::Labels(val)) = attr {
5434 return Ok(val);
5435 }
5436 }
5437 Err(ErrorContext::new_missing(
5438 "CtAttrs",
5439 "Labels",
5440 self.orig_loc,
5441 self.buf.as_ptr() as usize,
5442 ))
5443 }
5444 pub fn get_helper(&self) -> Result<&'a CStr, ErrorContext> {
5445 let mut iter = self.clone();
5446 iter.pos = 0;
5447 for attr in iter {
5448 if let Ok(CtAttrs::Helper(val)) = attr {
5449 return Ok(val);
5450 }
5451 }
5452 Err(ErrorContext::new_missing(
5453 "CtAttrs",
5454 "Helper",
5455 self.orig_loc,
5456 self.buf.as_ptr() as usize,
5457 ))
5458 }
5459 pub fn get_nat(&self) -> Result<IterableNatAttrs<'a>, ErrorContext> {
5460 let mut iter = self.clone();
5461 iter.pos = 0;
5462 for attr in iter {
5463 if let Ok(CtAttrs::Nat(val)) = attr {
5464 return Ok(val);
5465 }
5466 }
5467 Err(ErrorContext::new_missing(
5468 "CtAttrs",
5469 "Nat",
5470 self.orig_loc,
5471 self.buf.as_ptr() as usize,
5472 ))
5473 }
5474 pub fn get_force_commit(&self) -> Result<(), ErrorContext> {
5475 let mut iter = self.clone();
5476 iter.pos = 0;
5477 for attr in iter {
5478 if let Ok(CtAttrs::ForceCommit(val)) = attr {
5479 return Ok(val);
5480 }
5481 }
5482 Err(ErrorContext::new_missing(
5483 "CtAttrs",
5484 "ForceCommit",
5485 self.orig_loc,
5486 self.buf.as_ptr() as usize,
5487 ))
5488 }
5489 pub fn get_eventmask(&self) -> Result<u32, ErrorContext> {
5490 let mut iter = self.clone();
5491 iter.pos = 0;
5492 for attr in iter {
5493 if let Ok(CtAttrs::Eventmask(val)) = attr {
5494 return Ok(val);
5495 }
5496 }
5497 Err(ErrorContext::new_missing(
5498 "CtAttrs",
5499 "Eventmask",
5500 self.orig_loc,
5501 self.buf.as_ptr() as usize,
5502 ))
5503 }
5504 pub fn get_timeout(&self) -> Result<&'a CStr, ErrorContext> {
5505 let mut iter = self.clone();
5506 iter.pos = 0;
5507 for attr in iter {
5508 if let Ok(CtAttrs::Timeout(val)) = attr {
5509 return Ok(val);
5510 }
5511 }
5512 Err(ErrorContext::new_missing(
5513 "CtAttrs",
5514 "Timeout",
5515 self.orig_loc,
5516 self.buf.as_ptr() as usize,
5517 ))
5518 }
5519}
5520impl CtAttrs<'_> {
5521 pub fn new<'a>(buf: &'a [u8]) -> IterableCtAttrs<'a> {
5522 IterableCtAttrs::with_loc(buf, buf.as_ptr() as usize)
5523 }
5524 fn attr_from_type(r#type: u16) -> Option<&'static str> {
5525 let res = match r#type {
5526 1u16 => "Commit",
5527 2u16 => "Zone",
5528 3u16 => "Mark",
5529 4u16 => "Labels",
5530 5u16 => "Helper",
5531 6u16 => "Nat",
5532 7u16 => "ForceCommit",
5533 8u16 => "Eventmask",
5534 9u16 => "Timeout",
5535 _ => return None,
5536 };
5537 Some(res)
5538 }
5539}
5540#[derive(Clone, Copy, Default)]
5541pub struct IterableCtAttrs<'a> {
5542 buf: &'a [u8],
5543 pos: usize,
5544 orig_loc: usize,
5545}
5546impl<'a> IterableCtAttrs<'a> {
5547 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
5548 Self {
5549 buf,
5550 pos: 0,
5551 orig_loc,
5552 }
5553 }
5554 pub fn get_buf(&self) -> &'a [u8] {
5555 self.buf
5556 }
5557}
5558impl<'a> Iterator for IterableCtAttrs<'a> {
5559 type Item = Result<CtAttrs<'a>, ErrorContext>;
5560 fn next(&mut self) -> Option<Self::Item> {
5561 let mut pos;
5562 let mut r#type;
5563 loop {
5564 pos = self.pos;
5565 r#type = None;
5566 if self.buf.len() == self.pos {
5567 return None;
5568 }
5569 let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
5570 self.pos = self.buf.len();
5571 break;
5572 };
5573 r#type = Some(header.r#type);
5574 let res = match header.r#type {
5575 1u16 => CtAttrs::Commit(()),
5576 2u16 => CtAttrs::Zone({
5577 let res = parse_u16(next);
5578 let Some(val) = res else { break };
5579 val
5580 }),
5581 3u16 => CtAttrs::Mark({
5582 let res = Some(next);
5583 let Some(val) = res else { break };
5584 val
5585 }),
5586 4u16 => CtAttrs::Labels({
5587 let res = Some(next);
5588 let Some(val) = res else { break };
5589 val
5590 }),
5591 5u16 => CtAttrs::Helper({
5592 let res = CStr::from_bytes_with_nul(next).ok();
5593 let Some(val) = res else { break };
5594 val
5595 }),
5596 6u16 => CtAttrs::Nat({
5597 let res = Some(IterableNatAttrs::with_loc(next, self.orig_loc));
5598 let Some(val) = res else { break };
5599 val
5600 }),
5601 7u16 => CtAttrs::ForceCommit(()),
5602 8u16 => CtAttrs::Eventmask({
5603 let res = parse_u32(next);
5604 let Some(val) = res else { break };
5605 val
5606 }),
5607 9u16 => CtAttrs::Timeout({
5608 let res = CStr::from_bytes_with_nul(next).ok();
5609 let Some(val) = res else { break };
5610 val
5611 }),
5612 n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
5613 n => continue,
5614 };
5615 return Some(Ok(res));
5616 }
5617 Some(Err(ErrorContext::new(
5618 "CtAttrs",
5619 r#type.and_then(|t| CtAttrs::attr_from_type(t)),
5620 self.orig_loc,
5621 self.buf.as_ptr().wrapping_add(pos) as usize,
5622 )))
5623 }
5624}
5625impl<'a> std::fmt::Debug for IterableCtAttrs<'_> {
5626 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
5627 let mut fmt = f.debug_struct("CtAttrs");
5628 for attr in self.clone() {
5629 let attr = match attr {
5630 Ok(a) => a,
5631 Err(err) => {
5632 fmt.finish()?;
5633 f.write_str("Err(")?;
5634 err.fmt(f)?;
5635 return f.write_str(")");
5636 }
5637 };
5638 match attr {
5639 CtAttrs::Commit(val) => fmt.field("Commit", &val),
5640 CtAttrs::Zone(val) => fmt.field("Zone", &val),
5641 CtAttrs::Mark(val) => fmt.field("Mark", &val),
5642 CtAttrs::Labels(val) => fmt.field("Labels", &val),
5643 CtAttrs::Helper(val) => fmt.field("Helper", &val),
5644 CtAttrs::Nat(val) => fmt.field("Nat", &val),
5645 CtAttrs::ForceCommit(val) => fmt.field("ForceCommit", &val),
5646 CtAttrs::Eventmask(val) => fmt.field("Eventmask", &val),
5647 CtAttrs::Timeout(val) => fmt.field("Timeout", &val),
5648 };
5649 }
5650 fmt.finish()
5651 }
5652}
5653impl IterableCtAttrs<'_> {
5654 pub fn lookup_attr(
5655 &self,
5656 offset: usize,
5657 missing_type: Option<u16>,
5658 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
5659 let mut stack = Vec::new();
5660 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
5661 if missing_type.is_some() && cur == offset {
5662 stack.push(("CtAttrs", offset));
5663 return (stack, missing_type.and_then(|t| CtAttrs::attr_from_type(t)));
5664 }
5665 if cur > offset || cur + self.buf.len() < offset {
5666 return (stack, None);
5667 }
5668 let mut attrs = self.clone();
5669 let mut last_off = cur + attrs.pos;
5670 let mut missing = None;
5671 while let Some(attr) = attrs.next() {
5672 let Ok(attr) = attr else { break };
5673 match attr {
5674 CtAttrs::Commit(val) => {
5675 if last_off == offset {
5676 stack.push(("Commit", last_off));
5677 break;
5678 }
5679 }
5680 CtAttrs::Zone(val) => {
5681 if last_off == offset {
5682 stack.push(("Zone", last_off));
5683 break;
5684 }
5685 }
5686 CtAttrs::Mark(val) => {
5687 if last_off == offset {
5688 stack.push(("Mark", last_off));
5689 break;
5690 }
5691 }
5692 CtAttrs::Labels(val) => {
5693 if last_off == offset {
5694 stack.push(("Labels", last_off));
5695 break;
5696 }
5697 }
5698 CtAttrs::Helper(val) => {
5699 if last_off == offset {
5700 stack.push(("Helper", last_off));
5701 break;
5702 }
5703 }
5704 CtAttrs::Nat(val) => {
5705 (stack, missing) = val.lookup_attr(offset, missing_type);
5706 if !stack.is_empty() {
5707 break;
5708 }
5709 }
5710 CtAttrs::ForceCommit(val) => {
5711 if last_off == offset {
5712 stack.push(("ForceCommit", last_off));
5713 break;
5714 }
5715 }
5716 CtAttrs::Eventmask(val) => {
5717 if last_off == offset {
5718 stack.push(("Eventmask", last_off));
5719 break;
5720 }
5721 }
5722 CtAttrs::Timeout(val) => {
5723 if last_off == offset {
5724 stack.push(("Timeout", last_off));
5725 break;
5726 }
5727 }
5728 _ => {}
5729 };
5730 last_off = cur + attrs.pos;
5731 }
5732 if !stack.is_empty() {
5733 stack.push(("CtAttrs", cur));
5734 }
5735 (stack, missing)
5736 }
5737}
5738#[derive(Clone)]
5739pub enum NatAttrs<'a> {
5740 Src(()),
5741 Dst(()),
5742 IpMin(&'a [u8]),
5743 IpMax(&'a [u8]),
5744 ProtoMin(u16),
5745 ProtoMax(u16),
5746 Persistent(()),
5747 ProtoHash(()),
5748 ProtoRandom(()),
5749}
5750impl<'a> IterableNatAttrs<'a> {
5751 pub fn get_src(&self) -> Result<(), ErrorContext> {
5752 let mut iter = self.clone();
5753 iter.pos = 0;
5754 for attr in iter {
5755 if let Ok(NatAttrs::Src(val)) = attr {
5756 return Ok(val);
5757 }
5758 }
5759 Err(ErrorContext::new_missing(
5760 "NatAttrs",
5761 "Src",
5762 self.orig_loc,
5763 self.buf.as_ptr() as usize,
5764 ))
5765 }
5766 pub fn get_dst(&self) -> Result<(), ErrorContext> {
5767 let mut iter = self.clone();
5768 iter.pos = 0;
5769 for attr in iter {
5770 if let Ok(NatAttrs::Dst(val)) = attr {
5771 return Ok(val);
5772 }
5773 }
5774 Err(ErrorContext::new_missing(
5775 "NatAttrs",
5776 "Dst",
5777 self.orig_loc,
5778 self.buf.as_ptr() as usize,
5779 ))
5780 }
5781 pub fn get_ip_min(&self) -> Result<&'a [u8], ErrorContext> {
5782 let mut iter = self.clone();
5783 iter.pos = 0;
5784 for attr in iter {
5785 if let Ok(NatAttrs::IpMin(val)) = attr {
5786 return Ok(val);
5787 }
5788 }
5789 Err(ErrorContext::new_missing(
5790 "NatAttrs",
5791 "IpMin",
5792 self.orig_loc,
5793 self.buf.as_ptr() as usize,
5794 ))
5795 }
5796 pub fn get_ip_max(&self) -> Result<&'a [u8], ErrorContext> {
5797 let mut iter = self.clone();
5798 iter.pos = 0;
5799 for attr in iter {
5800 if let Ok(NatAttrs::IpMax(val)) = attr {
5801 return Ok(val);
5802 }
5803 }
5804 Err(ErrorContext::new_missing(
5805 "NatAttrs",
5806 "IpMax",
5807 self.orig_loc,
5808 self.buf.as_ptr() as usize,
5809 ))
5810 }
5811 pub fn get_proto_min(&self) -> Result<u16, ErrorContext> {
5812 let mut iter = self.clone();
5813 iter.pos = 0;
5814 for attr in iter {
5815 if let Ok(NatAttrs::ProtoMin(val)) = attr {
5816 return Ok(val);
5817 }
5818 }
5819 Err(ErrorContext::new_missing(
5820 "NatAttrs",
5821 "ProtoMin",
5822 self.orig_loc,
5823 self.buf.as_ptr() as usize,
5824 ))
5825 }
5826 pub fn get_proto_max(&self) -> Result<u16, ErrorContext> {
5827 let mut iter = self.clone();
5828 iter.pos = 0;
5829 for attr in iter {
5830 if let Ok(NatAttrs::ProtoMax(val)) = attr {
5831 return Ok(val);
5832 }
5833 }
5834 Err(ErrorContext::new_missing(
5835 "NatAttrs",
5836 "ProtoMax",
5837 self.orig_loc,
5838 self.buf.as_ptr() as usize,
5839 ))
5840 }
5841 pub fn get_persistent(&self) -> Result<(), ErrorContext> {
5842 let mut iter = self.clone();
5843 iter.pos = 0;
5844 for attr in iter {
5845 if let Ok(NatAttrs::Persistent(val)) = attr {
5846 return Ok(val);
5847 }
5848 }
5849 Err(ErrorContext::new_missing(
5850 "NatAttrs",
5851 "Persistent",
5852 self.orig_loc,
5853 self.buf.as_ptr() as usize,
5854 ))
5855 }
5856 pub fn get_proto_hash(&self) -> Result<(), ErrorContext> {
5857 let mut iter = self.clone();
5858 iter.pos = 0;
5859 for attr in iter {
5860 if let Ok(NatAttrs::ProtoHash(val)) = attr {
5861 return Ok(val);
5862 }
5863 }
5864 Err(ErrorContext::new_missing(
5865 "NatAttrs",
5866 "ProtoHash",
5867 self.orig_loc,
5868 self.buf.as_ptr() as usize,
5869 ))
5870 }
5871 pub fn get_proto_random(&self) -> Result<(), ErrorContext> {
5872 let mut iter = self.clone();
5873 iter.pos = 0;
5874 for attr in iter {
5875 if let Ok(NatAttrs::ProtoRandom(val)) = attr {
5876 return Ok(val);
5877 }
5878 }
5879 Err(ErrorContext::new_missing(
5880 "NatAttrs",
5881 "ProtoRandom",
5882 self.orig_loc,
5883 self.buf.as_ptr() as usize,
5884 ))
5885 }
5886}
5887impl NatAttrs<'_> {
5888 pub fn new<'a>(buf: &'a [u8]) -> IterableNatAttrs<'a> {
5889 IterableNatAttrs::with_loc(buf, buf.as_ptr() as usize)
5890 }
5891 fn attr_from_type(r#type: u16) -> Option<&'static str> {
5892 let res = match r#type {
5893 1u16 => "Src",
5894 2u16 => "Dst",
5895 3u16 => "IpMin",
5896 4u16 => "IpMax",
5897 5u16 => "ProtoMin",
5898 6u16 => "ProtoMax",
5899 7u16 => "Persistent",
5900 8u16 => "ProtoHash",
5901 9u16 => "ProtoRandom",
5902 _ => return None,
5903 };
5904 Some(res)
5905 }
5906}
5907#[derive(Clone, Copy, Default)]
5908pub struct IterableNatAttrs<'a> {
5909 buf: &'a [u8],
5910 pos: usize,
5911 orig_loc: usize,
5912}
5913impl<'a> IterableNatAttrs<'a> {
5914 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
5915 Self {
5916 buf,
5917 pos: 0,
5918 orig_loc,
5919 }
5920 }
5921 pub fn get_buf(&self) -> &'a [u8] {
5922 self.buf
5923 }
5924}
5925impl<'a> Iterator for IterableNatAttrs<'a> {
5926 type Item = Result<NatAttrs<'a>, ErrorContext>;
5927 fn next(&mut self) -> Option<Self::Item> {
5928 let mut pos;
5929 let mut r#type;
5930 loop {
5931 pos = self.pos;
5932 r#type = None;
5933 if self.buf.len() == self.pos {
5934 return None;
5935 }
5936 let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
5937 self.pos = self.buf.len();
5938 break;
5939 };
5940 r#type = Some(header.r#type);
5941 let res = match header.r#type {
5942 1u16 => NatAttrs::Src(()),
5943 2u16 => NatAttrs::Dst(()),
5944 3u16 => NatAttrs::IpMin({
5945 let res = Some(next);
5946 let Some(val) = res else { break };
5947 val
5948 }),
5949 4u16 => NatAttrs::IpMax({
5950 let res = Some(next);
5951 let Some(val) = res else { break };
5952 val
5953 }),
5954 5u16 => NatAttrs::ProtoMin({
5955 let res = parse_u16(next);
5956 let Some(val) = res else { break };
5957 val
5958 }),
5959 6u16 => NatAttrs::ProtoMax({
5960 let res = parse_u16(next);
5961 let Some(val) = res else { break };
5962 val
5963 }),
5964 7u16 => NatAttrs::Persistent(()),
5965 8u16 => NatAttrs::ProtoHash(()),
5966 9u16 => NatAttrs::ProtoRandom(()),
5967 n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
5968 n => continue,
5969 };
5970 return Some(Ok(res));
5971 }
5972 Some(Err(ErrorContext::new(
5973 "NatAttrs",
5974 r#type.and_then(|t| NatAttrs::attr_from_type(t)),
5975 self.orig_loc,
5976 self.buf.as_ptr().wrapping_add(pos) as usize,
5977 )))
5978 }
5979}
5980impl<'a> std::fmt::Debug for IterableNatAttrs<'_> {
5981 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
5982 let mut fmt = f.debug_struct("NatAttrs");
5983 for attr in self.clone() {
5984 let attr = match attr {
5985 Ok(a) => a,
5986 Err(err) => {
5987 fmt.finish()?;
5988 f.write_str("Err(")?;
5989 err.fmt(f)?;
5990 return f.write_str(")");
5991 }
5992 };
5993 match attr {
5994 NatAttrs::Src(val) => fmt.field("Src", &val),
5995 NatAttrs::Dst(val) => fmt.field("Dst", &val),
5996 NatAttrs::IpMin(val) => fmt.field("IpMin", &val),
5997 NatAttrs::IpMax(val) => fmt.field("IpMax", &val),
5998 NatAttrs::ProtoMin(val) => fmt.field("ProtoMin", &val),
5999 NatAttrs::ProtoMax(val) => fmt.field("ProtoMax", &val),
6000 NatAttrs::Persistent(val) => fmt.field("Persistent", &val),
6001 NatAttrs::ProtoHash(val) => fmt.field("ProtoHash", &val),
6002 NatAttrs::ProtoRandom(val) => fmt.field("ProtoRandom", &val),
6003 };
6004 }
6005 fmt.finish()
6006 }
6007}
6008impl IterableNatAttrs<'_> {
6009 pub fn lookup_attr(
6010 &self,
6011 offset: usize,
6012 missing_type: Option<u16>,
6013 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
6014 let mut stack = Vec::new();
6015 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
6016 if missing_type.is_some() && cur == offset {
6017 stack.push(("NatAttrs", offset));
6018 return (
6019 stack,
6020 missing_type.and_then(|t| NatAttrs::attr_from_type(t)),
6021 );
6022 }
6023 if cur > offset || cur + self.buf.len() < offset {
6024 return (stack, None);
6025 }
6026 let mut attrs = self.clone();
6027 let mut last_off = cur + attrs.pos;
6028 while let Some(attr) = attrs.next() {
6029 let Ok(attr) = attr else { break };
6030 match attr {
6031 NatAttrs::Src(val) => {
6032 if last_off == offset {
6033 stack.push(("Src", last_off));
6034 break;
6035 }
6036 }
6037 NatAttrs::Dst(val) => {
6038 if last_off == offset {
6039 stack.push(("Dst", last_off));
6040 break;
6041 }
6042 }
6043 NatAttrs::IpMin(val) => {
6044 if last_off == offset {
6045 stack.push(("IpMin", last_off));
6046 break;
6047 }
6048 }
6049 NatAttrs::IpMax(val) => {
6050 if last_off == offset {
6051 stack.push(("IpMax", last_off));
6052 break;
6053 }
6054 }
6055 NatAttrs::ProtoMin(val) => {
6056 if last_off == offset {
6057 stack.push(("ProtoMin", last_off));
6058 break;
6059 }
6060 }
6061 NatAttrs::ProtoMax(val) => {
6062 if last_off == offset {
6063 stack.push(("ProtoMax", last_off));
6064 break;
6065 }
6066 }
6067 NatAttrs::Persistent(val) => {
6068 if last_off == offset {
6069 stack.push(("Persistent", last_off));
6070 break;
6071 }
6072 }
6073 NatAttrs::ProtoHash(val) => {
6074 if last_off == offset {
6075 stack.push(("ProtoHash", last_off));
6076 break;
6077 }
6078 }
6079 NatAttrs::ProtoRandom(val) => {
6080 if last_off == offset {
6081 stack.push(("ProtoRandom", last_off));
6082 break;
6083 }
6084 }
6085 _ => {}
6086 };
6087 last_off = cur + attrs.pos;
6088 }
6089 if !stack.is_empty() {
6090 stack.push(("NatAttrs", cur));
6091 }
6092 (stack, None)
6093 }
6094}
6095#[derive(Clone)]
6096pub enum DecTtlAttrs<'a> {
6097 Action(IterableActionAttrs<'a>),
6098}
6099impl<'a> IterableDecTtlAttrs<'a> {
6100 pub fn get_action(&self) -> Result<IterableActionAttrs<'a>, ErrorContext> {
6101 let mut iter = self.clone();
6102 iter.pos = 0;
6103 for attr in iter {
6104 if let Ok(DecTtlAttrs::Action(val)) = attr {
6105 return Ok(val);
6106 }
6107 }
6108 Err(ErrorContext::new_missing(
6109 "DecTtlAttrs",
6110 "Action",
6111 self.orig_loc,
6112 self.buf.as_ptr() as usize,
6113 ))
6114 }
6115}
6116impl DecTtlAttrs<'_> {
6117 pub fn new<'a>(buf: &'a [u8]) -> IterableDecTtlAttrs<'a> {
6118 IterableDecTtlAttrs::with_loc(buf, buf.as_ptr() as usize)
6119 }
6120 fn attr_from_type(r#type: u16) -> Option<&'static str> {
6121 let res = match r#type {
6122 1u16 => "Action",
6123 _ => return None,
6124 };
6125 Some(res)
6126 }
6127}
6128#[derive(Clone, Copy, Default)]
6129pub struct IterableDecTtlAttrs<'a> {
6130 buf: &'a [u8],
6131 pos: usize,
6132 orig_loc: usize,
6133}
6134impl<'a> IterableDecTtlAttrs<'a> {
6135 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
6136 Self {
6137 buf,
6138 pos: 0,
6139 orig_loc,
6140 }
6141 }
6142 pub fn get_buf(&self) -> &'a [u8] {
6143 self.buf
6144 }
6145}
6146impl<'a> Iterator for IterableDecTtlAttrs<'a> {
6147 type Item = Result<DecTtlAttrs<'a>, ErrorContext>;
6148 fn next(&mut self) -> Option<Self::Item> {
6149 let mut pos;
6150 let mut r#type;
6151 loop {
6152 pos = self.pos;
6153 r#type = None;
6154 if self.buf.len() == self.pos {
6155 return None;
6156 }
6157 let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
6158 self.pos = self.buf.len();
6159 break;
6160 };
6161 r#type = Some(header.r#type);
6162 let res = match header.r#type {
6163 1u16 => DecTtlAttrs::Action({
6164 let res = Some(IterableActionAttrs::with_loc(next, self.orig_loc));
6165 let Some(val) = res else { break };
6166 val
6167 }),
6168 n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
6169 n => continue,
6170 };
6171 return Some(Ok(res));
6172 }
6173 Some(Err(ErrorContext::new(
6174 "DecTtlAttrs",
6175 r#type.and_then(|t| DecTtlAttrs::attr_from_type(t)),
6176 self.orig_loc,
6177 self.buf.as_ptr().wrapping_add(pos) as usize,
6178 )))
6179 }
6180}
6181impl<'a> std::fmt::Debug for IterableDecTtlAttrs<'_> {
6182 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
6183 let mut fmt = f.debug_struct("DecTtlAttrs");
6184 for attr in self.clone() {
6185 let attr = match attr {
6186 Ok(a) => a,
6187 Err(err) => {
6188 fmt.finish()?;
6189 f.write_str("Err(")?;
6190 err.fmt(f)?;
6191 return f.write_str(")");
6192 }
6193 };
6194 match attr {
6195 DecTtlAttrs::Action(val) => fmt.field("Action", &val),
6196 };
6197 }
6198 fmt.finish()
6199 }
6200}
6201impl IterableDecTtlAttrs<'_> {
6202 pub fn lookup_attr(
6203 &self,
6204 offset: usize,
6205 missing_type: Option<u16>,
6206 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
6207 let mut stack = Vec::new();
6208 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
6209 if missing_type.is_some() && cur == offset {
6210 stack.push(("DecTtlAttrs", offset));
6211 return (
6212 stack,
6213 missing_type.and_then(|t| DecTtlAttrs::attr_from_type(t)),
6214 );
6215 }
6216 if cur > offset || cur + self.buf.len() < offset {
6217 return (stack, None);
6218 }
6219 let mut attrs = self.clone();
6220 let mut last_off = cur + attrs.pos;
6221 let mut missing = None;
6222 while let Some(attr) = attrs.next() {
6223 let Ok(attr) = attr else { break };
6224 match attr {
6225 DecTtlAttrs::Action(val) => {
6226 (stack, missing) = val.lookup_attr(offset, missing_type);
6227 if !stack.is_empty() {
6228 break;
6229 }
6230 }
6231 _ => {}
6232 };
6233 last_off = cur + attrs.pos;
6234 }
6235 if !stack.is_empty() {
6236 stack.push(("DecTtlAttrs", cur));
6237 }
6238 (stack, missing)
6239 }
6240}
6241#[derive(Clone)]
6242pub enum VxlanExtAttrs {
6243 Gbp(u32),
6244}
6245impl<'a> IterableVxlanExtAttrs<'a> {
6246 pub fn get_gbp(&self) -> Result<u32, ErrorContext> {
6247 let mut iter = self.clone();
6248 iter.pos = 0;
6249 for attr in iter {
6250 if let Ok(VxlanExtAttrs::Gbp(val)) = attr {
6251 return Ok(val);
6252 }
6253 }
6254 Err(ErrorContext::new_missing(
6255 "VxlanExtAttrs",
6256 "Gbp",
6257 self.orig_loc,
6258 self.buf.as_ptr() as usize,
6259 ))
6260 }
6261}
6262impl VxlanExtAttrs {
6263 pub fn new<'a>(buf: &'a [u8]) -> IterableVxlanExtAttrs<'a> {
6264 IterableVxlanExtAttrs::with_loc(buf, buf.as_ptr() as usize)
6265 }
6266 fn attr_from_type(r#type: u16) -> Option<&'static str> {
6267 let res = match r#type {
6268 1u16 => "Gbp",
6269 _ => return None,
6270 };
6271 Some(res)
6272 }
6273}
6274#[derive(Clone, Copy, Default)]
6275pub struct IterableVxlanExtAttrs<'a> {
6276 buf: &'a [u8],
6277 pos: usize,
6278 orig_loc: usize,
6279}
6280impl<'a> IterableVxlanExtAttrs<'a> {
6281 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
6282 Self {
6283 buf,
6284 pos: 0,
6285 orig_loc,
6286 }
6287 }
6288 pub fn get_buf(&self) -> &'a [u8] {
6289 self.buf
6290 }
6291}
6292impl<'a> Iterator for IterableVxlanExtAttrs<'a> {
6293 type Item = Result<VxlanExtAttrs, ErrorContext>;
6294 fn next(&mut self) -> Option<Self::Item> {
6295 let mut pos;
6296 let mut r#type;
6297 loop {
6298 pos = self.pos;
6299 r#type = None;
6300 if self.buf.len() == self.pos {
6301 return None;
6302 }
6303 let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
6304 self.pos = self.buf.len();
6305 break;
6306 };
6307 r#type = Some(header.r#type);
6308 let res = match header.r#type {
6309 1u16 => VxlanExtAttrs::Gbp({
6310 let res = parse_u32(next);
6311 let Some(val) = res else { break };
6312 val
6313 }),
6314 n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
6315 n => continue,
6316 };
6317 return Some(Ok(res));
6318 }
6319 Some(Err(ErrorContext::new(
6320 "VxlanExtAttrs",
6321 r#type.and_then(|t| VxlanExtAttrs::attr_from_type(t)),
6322 self.orig_loc,
6323 self.buf.as_ptr().wrapping_add(pos) as usize,
6324 )))
6325 }
6326}
6327impl std::fmt::Debug for IterableVxlanExtAttrs<'_> {
6328 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
6329 let mut fmt = f.debug_struct("VxlanExtAttrs");
6330 for attr in self.clone() {
6331 let attr = match attr {
6332 Ok(a) => a,
6333 Err(err) => {
6334 fmt.finish()?;
6335 f.write_str("Err(")?;
6336 err.fmt(f)?;
6337 return f.write_str(")");
6338 }
6339 };
6340 match attr {
6341 VxlanExtAttrs::Gbp(val) => fmt.field("Gbp", &val),
6342 };
6343 }
6344 fmt.finish()
6345 }
6346}
6347impl IterableVxlanExtAttrs<'_> {
6348 pub fn lookup_attr(
6349 &self,
6350 offset: usize,
6351 missing_type: Option<u16>,
6352 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
6353 let mut stack = Vec::new();
6354 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
6355 if missing_type.is_some() && cur == offset {
6356 stack.push(("VxlanExtAttrs", offset));
6357 return (
6358 stack,
6359 missing_type.and_then(|t| VxlanExtAttrs::attr_from_type(t)),
6360 );
6361 }
6362 if cur > offset || cur + self.buf.len() < offset {
6363 return (stack, None);
6364 }
6365 let mut attrs = self.clone();
6366 let mut last_off = cur + attrs.pos;
6367 while let Some(attr) = attrs.next() {
6368 let Ok(attr) = attr else { break };
6369 match attr {
6370 VxlanExtAttrs::Gbp(val) => {
6371 if last_off == offset {
6372 stack.push(("Gbp", last_off));
6373 break;
6374 }
6375 }
6376 _ => {}
6377 };
6378 last_off = cur + attrs.pos;
6379 }
6380 if !stack.is_empty() {
6381 stack.push(("VxlanExtAttrs", cur));
6382 }
6383 (stack, None)
6384 }
6385}
6386#[derive(Clone)]
6387pub enum PsampleAttrs<'a> {
6388 Group(u32),
6389 Cookie(&'a [u8]),
6390}
6391impl<'a> IterablePsampleAttrs<'a> {
6392 pub fn get_group(&self) -> Result<u32, ErrorContext> {
6393 let mut iter = self.clone();
6394 iter.pos = 0;
6395 for attr in iter {
6396 if let Ok(PsampleAttrs::Group(val)) = attr {
6397 return Ok(val);
6398 }
6399 }
6400 Err(ErrorContext::new_missing(
6401 "PsampleAttrs",
6402 "Group",
6403 self.orig_loc,
6404 self.buf.as_ptr() as usize,
6405 ))
6406 }
6407 pub fn get_cookie(&self) -> Result<&'a [u8], ErrorContext> {
6408 let mut iter = self.clone();
6409 iter.pos = 0;
6410 for attr in iter {
6411 if let Ok(PsampleAttrs::Cookie(val)) = attr {
6412 return Ok(val);
6413 }
6414 }
6415 Err(ErrorContext::new_missing(
6416 "PsampleAttrs",
6417 "Cookie",
6418 self.orig_loc,
6419 self.buf.as_ptr() as usize,
6420 ))
6421 }
6422}
6423impl PsampleAttrs<'_> {
6424 pub fn new<'a>(buf: &'a [u8]) -> IterablePsampleAttrs<'a> {
6425 IterablePsampleAttrs::with_loc(buf, buf.as_ptr() as usize)
6426 }
6427 fn attr_from_type(r#type: u16) -> Option<&'static str> {
6428 let res = match r#type {
6429 1u16 => "Group",
6430 2u16 => "Cookie",
6431 _ => return None,
6432 };
6433 Some(res)
6434 }
6435}
6436#[derive(Clone, Copy, Default)]
6437pub struct IterablePsampleAttrs<'a> {
6438 buf: &'a [u8],
6439 pos: usize,
6440 orig_loc: usize,
6441}
6442impl<'a> IterablePsampleAttrs<'a> {
6443 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
6444 Self {
6445 buf,
6446 pos: 0,
6447 orig_loc,
6448 }
6449 }
6450 pub fn get_buf(&self) -> &'a [u8] {
6451 self.buf
6452 }
6453}
6454impl<'a> Iterator for IterablePsampleAttrs<'a> {
6455 type Item = Result<PsampleAttrs<'a>, ErrorContext>;
6456 fn next(&mut self) -> Option<Self::Item> {
6457 let mut pos;
6458 let mut r#type;
6459 loop {
6460 pos = self.pos;
6461 r#type = None;
6462 if self.buf.len() == self.pos {
6463 return None;
6464 }
6465 let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
6466 self.pos = self.buf.len();
6467 break;
6468 };
6469 r#type = Some(header.r#type);
6470 let res = match header.r#type {
6471 1u16 => PsampleAttrs::Group({
6472 let res = parse_u32(next);
6473 let Some(val) = res else { break };
6474 val
6475 }),
6476 2u16 => PsampleAttrs::Cookie({
6477 let res = Some(next);
6478 let Some(val) = res else { break };
6479 val
6480 }),
6481 n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
6482 n => continue,
6483 };
6484 return Some(Ok(res));
6485 }
6486 Some(Err(ErrorContext::new(
6487 "PsampleAttrs",
6488 r#type.and_then(|t| PsampleAttrs::attr_from_type(t)),
6489 self.orig_loc,
6490 self.buf.as_ptr().wrapping_add(pos) as usize,
6491 )))
6492 }
6493}
6494impl<'a> std::fmt::Debug for IterablePsampleAttrs<'_> {
6495 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
6496 let mut fmt = f.debug_struct("PsampleAttrs");
6497 for attr in self.clone() {
6498 let attr = match attr {
6499 Ok(a) => a,
6500 Err(err) => {
6501 fmt.finish()?;
6502 f.write_str("Err(")?;
6503 err.fmt(f)?;
6504 return f.write_str(")");
6505 }
6506 };
6507 match attr {
6508 PsampleAttrs::Group(val) => fmt.field("Group", &val),
6509 PsampleAttrs::Cookie(val) => fmt.field("Cookie", &val),
6510 };
6511 }
6512 fmt.finish()
6513 }
6514}
6515impl IterablePsampleAttrs<'_> {
6516 pub fn lookup_attr(
6517 &self,
6518 offset: usize,
6519 missing_type: Option<u16>,
6520 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
6521 let mut stack = Vec::new();
6522 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
6523 if missing_type.is_some() && cur == offset {
6524 stack.push(("PsampleAttrs", offset));
6525 return (
6526 stack,
6527 missing_type.and_then(|t| PsampleAttrs::attr_from_type(t)),
6528 );
6529 }
6530 if cur > offset || cur + self.buf.len() < offset {
6531 return (stack, None);
6532 }
6533 let mut attrs = self.clone();
6534 let mut last_off = cur + attrs.pos;
6535 while let Some(attr) = attrs.next() {
6536 let Ok(attr) = attr else { break };
6537 match attr {
6538 PsampleAttrs::Group(val) => {
6539 if last_off == offset {
6540 stack.push(("Group", last_off));
6541 break;
6542 }
6543 }
6544 PsampleAttrs::Cookie(val) => {
6545 if last_off == offset {
6546 stack.push(("Cookie", last_off));
6547 break;
6548 }
6549 }
6550 _ => {}
6551 };
6552 last_off = cur + attrs.pos;
6553 }
6554 if !stack.is_empty() {
6555 stack.push(("PsampleAttrs", cur));
6556 }
6557 (stack, None)
6558 }
6559}
6560pub struct PushFlowAttrs<Prev: Pusher> {
6561 pub(crate) prev: Option<Prev>,
6562 pub(crate) header_offset: Option<usize>,
6563}
6564impl<Prev: Pusher> Pusher for PushFlowAttrs<Prev> {
6565 fn as_vec_mut(&mut self) -> &mut Vec<u8> {
6566 self.prev.as_mut().unwrap().as_vec_mut()
6567 }
6568 fn as_vec(&self) -> &Vec<u8> {
6569 self.prev.as_ref().unwrap().as_vec()
6570 }
6571}
6572impl<Prev: Pusher> PushFlowAttrs<Prev> {
6573 pub fn new(prev: Prev) -> Self {
6574 Self {
6575 prev: Some(prev),
6576 header_offset: None,
6577 }
6578 }
6579 pub fn end_nested(mut self) -> Prev {
6580 let mut prev = self.prev.take().unwrap();
6581 if let Some(header_offset) = &self.header_offset {
6582 finalize_nested_header(prev.as_vec_mut(), *header_offset);
6583 }
6584 prev
6585 }
6586 #[doc = "Nested attributes specifying the flow key. Always present in\nnotifications. Required for all requests (except dumps).\n"]
6587 pub fn nested_key(mut self) -> PushKeyAttrs<Self> {
6588 let header_offset = push_nested_header(self.as_vec_mut(), 1u16);
6589 PushKeyAttrs {
6590 prev: Some(self),
6591 header_offset: Some(header_offset),
6592 }
6593 }
6594 #[doc = "Nested attributes specifying the actions to take for packets that match\nthe key. Always present in notifications. Required for OVS_FLOW_CMD_NEW\nrequests, optional for OVS_FLOW_CMD_SET requests. An OVS_FLOW_CMD_SET\nwithout OVS_FLOW_ATTR_ACTIONS will not modify the actions. To clear the\nactions, an OVS_FLOW_ATTR_ACTIONS without any nested attributes must be\ngiven.\n"]
6595 pub fn nested_actions(mut self) -> PushActionAttrs<Self> {
6596 let header_offset = push_nested_header(self.as_vec_mut(), 2u16);
6597 PushActionAttrs {
6598 prev: Some(self),
6599 header_offset: Some(header_offset),
6600 }
6601 }
6602 #[doc = "Statistics for this flow. Present in notifications if the stats would be\nnonzero. Ignored in requests.\n"]
6603 pub fn push_stats(mut self, value: OvsFlowStats) -> Self {
6604 push_header(self.as_vec_mut(), 3u16, value.as_slice().len() as u16);
6605 self.as_vec_mut().extend(value.as_slice());
6606 self
6607 }
6608 #[doc = "An 8-bit value giving the ORed value of all of the TCP flags seen on\npackets in this flow. Only present in notifications for TCP flows, and\nonly if it would be nonzero. Ignored in requests.\n"]
6609 pub fn push_tcp_flags(mut self, value: u8) -> Self {
6610 push_header(self.as_vec_mut(), 4u16, 1 as u16);
6611 self.as_vec_mut().extend(value.to_ne_bytes());
6612 self
6613 }
6614 #[doc = "A 64-bit integer giving the time, in milliseconds on the system\nmonotonic clock, at which a packet was last processed for this flow.\nOnly present in notifications if a packet has been processed for this\nflow. Ignored in requests.\n"]
6615 pub fn push_used(mut self, value: u64) -> Self {
6616 push_header(self.as_vec_mut(), 5u16, 8 as u16);
6617 self.as_vec_mut().extend(value.to_ne_bytes());
6618 self
6619 }
6620 #[doc = "If present in a OVS_FLOW_CMD_SET request, clears the last-used time,\naccumulated TCP flags, and statistics for this flow. Otherwise ignored\nin requests. Never present in notifications.\n"]
6621 pub fn push_clear(mut self, value: ()) -> Self {
6622 push_header(self.as_vec_mut(), 6u16, 0 as u16);
6623 self
6624 }
6625 #[doc = "Nested attributes specifying the mask bits for wildcarded flow match.\nMask bit value \\'1\\' specifies exact match with corresponding flow key\nbit, while mask bit value \\'0\\' specifies a wildcarded match. Omitting\nattribute is treated as wildcarding all corresponding fields. Optional\nfor all requests. If not present, all flow key bits are exact match\nbits.\n"]
6626 pub fn nested_mask(mut self) -> PushKeyAttrs<Self> {
6627 let header_offset = push_nested_header(self.as_vec_mut(), 7u16);
6628 PushKeyAttrs {
6629 prev: Some(self),
6630 header_offset: Some(header_offset),
6631 }
6632 }
6633 #[doc = "Flow operation is a feature probe, error logging should be suppressed.\n"]
6634 pub fn push_probe(mut self, value: &[u8]) -> Self {
6635 push_header(self.as_vec_mut(), 8u16, value.len() as u16);
6636 self.as_vec_mut().extend(value);
6637 self
6638 }
6639 #[doc = "A value between 1-16 octets specifying a unique identifier for the flow.\nCauses the flow to be indexed by this value rather than the value of the\nOVS_FLOW_ATTR_KEY attribute. Optional for all requests. Present in\nnotifications if the flow was created with this attribute.\n"]
6640 pub fn push_ufid(mut self, value: &[u8]) -> Self {
6641 push_header(self.as_vec_mut(), 9u16, value.len() as u16);
6642 self.as_vec_mut().extend(value);
6643 self
6644 }
6645 #[doc = "A 32-bit value of ORed flags that provide alternative semantics for flow\ninstallation and retrieval. Optional for all requests.\n\nAssociated type: [`OvsUfidFlags`] (enum)"]
6646 pub fn push_ufid_flags(mut self, value: u32) -> Self {
6647 push_header(self.as_vec_mut(), 10u16, 4 as u16);
6648 self.as_vec_mut().extend(value.to_ne_bytes());
6649 self
6650 }
6651 pub fn push_pad(mut self, value: &[u8]) -> Self {
6652 push_header(self.as_vec_mut(), 11u16, value.len() as u16);
6653 self.as_vec_mut().extend(value);
6654 self
6655 }
6656}
6657impl<Prev: Pusher> Drop for PushFlowAttrs<Prev> {
6658 fn drop(&mut self) {
6659 if let Some(prev) = &mut self.prev {
6660 if let Some(header_offset) = &self.header_offset {
6661 finalize_nested_header(prev.as_vec_mut(), *header_offset);
6662 }
6663 }
6664 }
6665}
6666pub struct PushKeyAttrs<Prev: Pusher> {
6667 pub(crate) prev: Option<Prev>,
6668 pub(crate) header_offset: Option<usize>,
6669}
6670impl<Prev: Pusher> Pusher for PushKeyAttrs<Prev> {
6671 fn as_vec_mut(&mut self) -> &mut Vec<u8> {
6672 self.prev.as_mut().unwrap().as_vec_mut()
6673 }
6674 fn as_vec(&self) -> &Vec<u8> {
6675 self.prev.as_ref().unwrap().as_vec()
6676 }
6677}
6678impl<Prev: Pusher> PushKeyAttrs<Prev> {
6679 pub fn new(prev: Prev) -> Self {
6680 Self {
6681 prev: Some(prev),
6682 header_offset: None,
6683 }
6684 }
6685 pub fn end_nested(mut self) -> Prev {
6686 let mut prev = self.prev.take().unwrap();
6687 if let Some(header_offset) = &self.header_offset {
6688 finalize_nested_header(prev.as_vec_mut(), *header_offset);
6689 }
6690 prev
6691 }
6692 pub fn nested_encap(mut self) -> PushKeyAttrs<Self> {
6693 let header_offset = push_nested_header(self.as_vec_mut(), 1u16);
6694 PushKeyAttrs {
6695 prev: Some(self),
6696 header_offset: Some(header_offset),
6697 }
6698 }
6699 pub fn push_priority(mut self, value: u32) -> Self {
6700 push_header(self.as_vec_mut(), 2u16, 4 as u16);
6701 self.as_vec_mut().extend(value.to_ne_bytes());
6702 self
6703 }
6704 pub fn push_in_port(mut self, value: u32) -> Self {
6705 push_header(self.as_vec_mut(), 3u16, 4 as u16);
6706 self.as_vec_mut().extend(value.to_ne_bytes());
6707 self
6708 }
6709 #[doc = "struct ovs_key_ethernet\n"]
6710 pub fn push_ethernet(mut self, value: OvsKeyEthernet) -> Self {
6711 push_header(self.as_vec_mut(), 4u16, value.as_slice().len() as u16);
6712 self.as_vec_mut().extend(value.as_slice());
6713 self
6714 }
6715 pub fn push_vlan(mut self, value: u16) -> Self {
6716 push_header(self.as_vec_mut(), 5u16, 2 as u16);
6717 self.as_vec_mut().extend(value.to_be_bytes());
6718 self
6719 }
6720 pub fn push_ethertype(mut self, value: u16) -> Self {
6721 push_header(self.as_vec_mut(), 6u16, 2 as u16);
6722 self.as_vec_mut().extend(value.to_be_bytes());
6723 self
6724 }
6725 pub fn push_ipv4(mut self, value: OvsKeyIpv4) -> Self {
6726 push_header(self.as_vec_mut(), 7u16, value.as_slice().len() as u16);
6727 self.as_vec_mut().extend(value.as_slice());
6728 self
6729 }
6730 #[doc = "struct ovs_key_ipv6\n"]
6731 pub fn push_ipv6(mut self, value: OvsKeyIpv6) -> Self {
6732 push_header(self.as_vec_mut(), 8u16, value.as_slice().len() as u16);
6733 self.as_vec_mut().extend(value.as_slice());
6734 self
6735 }
6736 pub fn push_tcp(mut self, value: OvsKeyTcp) -> Self {
6737 push_header(self.as_vec_mut(), 9u16, value.as_slice().len() as u16);
6738 self.as_vec_mut().extend(value.as_slice());
6739 self
6740 }
6741 pub fn push_udp(mut self, value: OvsKeyUdp) -> Self {
6742 push_header(self.as_vec_mut(), 10u16, value.as_slice().len() as u16);
6743 self.as_vec_mut().extend(value.as_slice());
6744 self
6745 }
6746 pub fn push_icmp(mut self, value: OvsKeyIcmp) -> Self {
6747 push_header(self.as_vec_mut(), 11u16, value.as_slice().len() as u16);
6748 self.as_vec_mut().extend(value.as_slice());
6749 self
6750 }
6751 pub fn push_icmpv6(mut self, value: OvsKeyIcmp) -> Self {
6752 push_header(self.as_vec_mut(), 12u16, value.as_slice().len() as u16);
6753 self.as_vec_mut().extend(value.as_slice());
6754 self
6755 }
6756 #[doc = "struct ovs_key_arp\n"]
6757 pub fn push_arp(mut self, value: OvsKeyArp) -> Self {
6758 push_header(self.as_vec_mut(), 13u16, value.as_slice().len() as u16);
6759 self.as_vec_mut().extend(value.as_slice());
6760 self
6761 }
6762 #[doc = "struct ovs_key_nd\n"]
6763 pub fn push_nd(mut self, value: OvsKeyNd) -> Self {
6764 push_header(self.as_vec_mut(), 14u16, value.as_slice().len() as u16);
6765 self.as_vec_mut().extend(value.as_slice());
6766 self
6767 }
6768 pub fn push_skb_mark(mut self, value: u32) -> Self {
6769 push_header(self.as_vec_mut(), 15u16, 4 as u16);
6770 self.as_vec_mut().extend(value.to_ne_bytes());
6771 self
6772 }
6773 pub fn nested_tunnel(mut self) -> PushTunnelKeyAttrs<Self> {
6774 let header_offset = push_nested_header(self.as_vec_mut(), 16u16);
6775 PushTunnelKeyAttrs {
6776 prev: Some(self),
6777 header_offset: Some(header_offset),
6778 }
6779 }
6780 pub fn push_sctp(mut self, value: OvsKeySctp) -> Self {
6781 push_header(self.as_vec_mut(), 17u16, value.as_slice().len() as u16);
6782 self.as_vec_mut().extend(value.as_slice());
6783 self
6784 }
6785 pub fn push_tcp_flags(mut self, value: u16) -> Self {
6786 push_header(self.as_vec_mut(), 18u16, 2 as u16);
6787 self.as_vec_mut().extend(value.to_be_bytes());
6788 self
6789 }
6790 #[doc = "Value 0 indicates the hash is not computed by the datapath.\n"]
6791 pub fn push_dp_hash(mut self, value: u32) -> Self {
6792 push_header(self.as_vec_mut(), 19u16, 4 as u16);
6793 self.as_vec_mut().extend(value.to_ne_bytes());
6794 self
6795 }
6796 pub fn push_recirc_id(mut self, value: u32) -> Self {
6797 push_header(self.as_vec_mut(), 20u16, 4 as u16);
6798 self.as_vec_mut().extend(value.to_ne_bytes());
6799 self
6800 }
6801 pub fn push_mpls(mut self, value: OvsKeyMpls) -> Self {
6802 push_header(self.as_vec_mut(), 21u16, value.as_slice().len() as u16);
6803 self.as_vec_mut().extend(value.as_slice());
6804 self
6805 }
6806 #[doc = "Associated type: [`CtStateFlags`] (1 bit per enumeration)"]
6807 pub fn push_ct_state(mut self, value: u32) -> Self {
6808 push_header(self.as_vec_mut(), 22u16, 4 as u16);
6809 self.as_vec_mut().extend(value.to_ne_bytes());
6810 self
6811 }
6812 #[doc = "connection tracking zone\n"]
6813 pub fn push_ct_zone(mut self, value: u16) -> Self {
6814 push_header(self.as_vec_mut(), 23u16, 2 as u16);
6815 self.as_vec_mut().extend(value.to_ne_bytes());
6816 self
6817 }
6818 #[doc = "connection tracking mark\n"]
6819 pub fn push_ct_mark(mut self, value: u32) -> Self {
6820 push_header(self.as_vec_mut(), 24u16, 4 as u16);
6821 self.as_vec_mut().extend(value.to_ne_bytes());
6822 self
6823 }
6824 #[doc = "16-octet connection tracking label\n"]
6825 pub fn push_ct_labels(mut self, value: &[u8]) -> Self {
6826 push_header(self.as_vec_mut(), 25u16, value.len() as u16);
6827 self.as_vec_mut().extend(value);
6828 self
6829 }
6830 pub fn push_ct_orig_tuple_ipv4(mut self, value: OvsKeyCtTupleIpv4) -> Self {
6831 push_header(self.as_vec_mut(), 26u16, value.as_slice().len() as u16);
6832 self.as_vec_mut().extend(value.as_slice());
6833 self
6834 }
6835 #[doc = "struct ovs_key_ct_tuple_ipv6\n"]
6836 pub fn push_ct_orig_tuple_ipv6(mut self, value: &[u8]) -> Self {
6837 push_header(self.as_vec_mut(), 27u16, value.len() as u16);
6838 self.as_vec_mut().extend(value);
6839 self
6840 }
6841 pub fn nested_nsh(mut self) -> PushOvsNshKeyAttrs<Self> {
6842 let header_offset = push_nested_header(self.as_vec_mut(), 28u16);
6843 PushOvsNshKeyAttrs {
6844 prev: Some(self),
6845 header_offset: Some(header_offset),
6846 }
6847 }
6848 #[doc = "Should not be sent to the kernel\n"]
6849 pub fn push_packet_type(mut self, value: u32) -> Self {
6850 push_header(self.as_vec_mut(), 29u16, 4 as u16);
6851 self.as_vec_mut().extend(value.to_be_bytes());
6852 self
6853 }
6854 #[doc = "Should not be sent to the kernel\n"]
6855 pub fn push_nd_extensions(mut self, value: &[u8]) -> Self {
6856 push_header(self.as_vec_mut(), 30u16, value.len() as u16);
6857 self.as_vec_mut().extend(value);
6858 self
6859 }
6860 #[doc = "struct ip_tunnel_info\n"]
6861 pub fn push_tunnel_info(mut self, value: &[u8]) -> Self {
6862 push_header(self.as_vec_mut(), 31u16, value.len() as u16);
6863 self.as_vec_mut().extend(value);
6864 self
6865 }
6866 #[doc = "struct ovs_key_ipv6_exthdr\n"]
6867 pub fn push_ipv6_exthdrs(mut self, value: OvsKeyIpv6Exthdrs) -> Self {
6868 push_header(self.as_vec_mut(), 32u16, value.as_slice().len() as u16);
6869 self.as_vec_mut().extend(value.as_slice());
6870 self
6871 }
6872}
6873impl<Prev: Pusher> Drop for PushKeyAttrs<Prev> {
6874 fn drop(&mut self) {
6875 if let Some(prev) = &mut self.prev {
6876 if let Some(header_offset) = &self.header_offset {
6877 finalize_nested_header(prev.as_vec_mut(), *header_offset);
6878 }
6879 }
6880 }
6881}
6882pub struct PushActionAttrs<Prev: Pusher> {
6883 pub(crate) prev: Option<Prev>,
6884 pub(crate) header_offset: Option<usize>,
6885}
6886impl<Prev: Pusher> Pusher for PushActionAttrs<Prev> {
6887 fn as_vec_mut(&mut self) -> &mut Vec<u8> {
6888 self.prev.as_mut().unwrap().as_vec_mut()
6889 }
6890 fn as_vec(&self) -> &Vec<u8> {
6891 self.prev.as_ref().unwrap().as_vec()
6892 }
6893}
6894impl<Prev: Pusher> PushActionAttrs<Prev> {
6895 pub fn new(prev: Prev) -> Self {
6896 Self {
6897 prev: Some(prev),
6898 header_offset: None,
6899 }
6900 }
6901 pub fn end_nested(mut self) -> Prev {
6902 let mut prev = self.prev.take().unwrap();
6903 if let Some(header_offset) = &self.header_offset {
6904 finalize_nested_header(prev.as_vec_mut(), *header_offset);
6905 }
6906 prev
6907 }
6908 #[doc = "ovs port number in datapath\n"]
6909 pub fn push_output(mut self, value: u32) -> Self {
6910 push_header(self.as_vec_mut(), 1u16, 4 as u16);
6911 self.as_vec_mut().extend(value.to_ne_bytes());
6912 self
6913 }
6914 pub fn nested_userspace(mut self) -> PushUserspaceAttrs<Self> {
6915 let header_offset = push_nested_header(self.as_vec_mut(), 2u16);
6916 PushUserspaceAttrs {
6917 prev: Some(self),
6918 header_offset: Some(header_offset),
6919 }
6920 }
6921 #[doc = "Replaces the contents of an existing header. The single nested attribute\nspecifies a header to modify and its value.\n"]
6922 pub fn nested_set(mut self) -> PushKeyAttrs<Self> {
6923 let header_offset = push_nested_header(self.as_vec_mut(), 3u16);
6924 PushKeyAttrs {
6925 prev: Some(self),
6926 header_offset: Some(header_offset),
6927 }
6928 }
6929 #[doc = "Push a new outermost 802.1Q or 802.1ad header onto the packet.\n"]
6930 pub fn push_push_vlan(mut self, value: OvsActionPushVlan) -> Self {
6931 push_header(self.as_vec_mut(), 4u16, value.as_slice().len() as u16);
6932 self.as_vec_mut().extend(value.as_slice());
6933 self
6934 }
6935 #[doc = "Pop the outermost 802.1Q or 802.1ad header from the packet.\n"]
6936 pub fn push_pop_vlan(mut self, value: ()) -> Self {
6937 push_header(self.as_vec_mut(), 5u16, 0 as u16);
6938 self
6939 }
6940 #[doc = "Probabilistically executes actions, as specified in the nested\nattributes.\n"]
6941 pub fn nested_sample(mut self) -> PushSampleAttrs<Self> {
6942 let header_offset = push_nested_header(self.as_vec_mut(), 6u16);
6943 PushSampleAttrs {
6944 prev: Some(self),
6945 header_offset: Some(header_offset),
6946 }
6947 }
6948 #[doc = "recirc id\n"]
6949 pub fn push_recirc(mut self, value: u32) -> Self {
6950 push_header(self.as_vec_mut(), 7u16, 4 as u16);
6951 self.as_vec_mut().extend(value.to_ne_bytes());
6952 self
6953 }
6954 pub fn push_hash(mut self, value: OvsActionHash) -> Self {
6955 push_header(self.as_vec_mut(), 8u16, value.as_slice().len() as u16);
6956 self.as_vec_mut().extend(value.as_slice());
6957 self
6958 }
6959 #[doc = "Push a new MPLS label stack entry onto the top of the packets MPLS label\nstack. Set the ethertype of the encapsulating frame to either\nETH_P_MPLS_UC or ETH_P_MPLS_MC to indicate the new packet contents.\n"]
6960 pub fn push_push_mpls(mut self, value: OvsActionPushMpls) -> Self {
6961 push_header(self.as_vec_mut(), 9u16, value.as_slice().len() as u16);
6962 self.as_vec_mut().extend(value.as_slice());
6963 self
6964 }
6965 #[doc = "ethertype\n"]
6966 pub fn push_pop_mpls(mut self, value: u16) -> Self {
6967 push_header(self.as_vec_mut(), 10u16, 2 as u16);
6968 self.as_vec_mut().extend(value.to_be_bytes());
6969 self
6970 }
6971 #[doc = "Replaces the contents of an existing header. A nested attribute\nspecifies a header to modify, its value, and a mask. For every bit set\nin the mask, the corresponding bit value is copied from the value to the\npacket header field, rest of the bits are left unchanged. The non-masked\nvalue bits must be passed in as zeroes. Masking is not supported for the\nOVS_KEY_ATTR_TUNNEL attribute.\n"]
6972 pub fn nested_set_masked(mut self) -> PushKeyAttrs<Self> {
6973 let header_offset = push_nested_header(self.as_vec_mut(), 11u16);
6974 PushKeyAttrs {
6975 prev: Some(self),
6976 header_offset: Some(header_offset),
6977 }
6978 }
6979 #[doc = "Track the connection. Populate the conntrack-related entries in the flow\nkey.\n"]
6980 pub fn nested_ct(mut self) -> PushCtAttrs<Self> {
6981 let header_offset = push_nested_header(self.as_vec_mut(), 12u16);
6982 PushCtAttrs {
6983 prev: Some(self),
6984 header_offset: Some(header_offset),
6985 }
6986 }
6987 #[doc = "struct ovs_action_trunc is a u32 max length\n"]
6988 pub fn push_trunc(mut self, value: u32) -> Self {
6989 push_header(self.as_vec_mut(), 13u16, 4 as u16);
6990 self.as_vec_mut().extend(value.to_ne_bytes());
6991 self
6992 }
6993 #[doc = "struct ovs_action_push_eth\n"]
6994 pub fn push_push_eth(mut self, value: &[u8]) -> Self {
6995 push_header(self.as_vec_mut(), 14u16, value.len() as u16);
6996 self.as_vec_mut().extend(value);
6997 self
6998 }
6999 pub fn push_pop_eth(mut self, value: ()) -> Self {
7000 push_header(self.as_vec_mut(), 15u16, 0 as u16);
7001 self
7002 }
7003 pub fn push_ct_clear(mut self, value: ()) -> Self {
7004 push_header(self.as_vec_mut(), 16u16, 0 as u16);
7005 self
7006 }
7007 #[doc = "Push NSH header to the packet.\n"]
7008 pub fn nested_push_nsh(mut self) -> PushOvsNshKeyAttrs<Self> {
7009 let header_offset = push_nested_header(self.as_vec_mut(), 17u16);
7010 PushOvsNshKeyAttrs {
7011 prev: Some(self),
7012 header_offset: Some(header_offset),
7013 }
7014 }
7015 #[doc = "Pop the outermost NSH header off the packet.\n"]
7016 pub fn push_pop_nsh(mut self, value: ()) -> Self {
7017 push_header(self.as_vec_mut(), 18u16, 0 as u16);
7018 self
7019 }
7020 #[doc = "Run packet through a meter, which may drop the packet, or modify the\npacket (e.g., change the DSCP field)\n"]
7021 pub fn push_meter(mut self, value: u32) -> Self {
7022 push_header(self.as_vec_mut(), 19u16, 4 as u16);
7023 self.as_vec_mut().extend(value.to_ne_bytes());
7024 self
7025 }
7026 #[doc = "Make a copy of the packet and execute a list of actions without\naffecting the original packet and key.\n"]
7027 pub fn nested_clone(mut self) -> PushActionAttrs<Self> {
7028 let header_offset = push_nested_header(self.as_vec_mut(), 20u16);
7029 PushActionAttrs {
7030 prev: Some(self),
7031 header_offset: Some(header_offset),
7032 }
7033 }
7034 #[doc = "Check the packet length and execute a set of actions if greater than the\nspecified packet length, else execute another set of actions.\n"]
7035 pub fn nested_check_pkt_len(mut self) -> PushCheckPktLenAttrs<Self> {
7036 let header_offset = push_nested_header(self.as_vec_mut(), 21u16);
7037 PushCheckPktLenAttrs {
7038 prev: Some(self),
7039 header_offset: Some(header_offset),
7040 }
7041 }
7042 #[doc = "Push a new MPLS label stack entry at the start of the packet or at the\nstart of the l3 header depending on the value of l3 tunnel flag in the\ntun_flags field of this OVS_ACTION_ATTR_ADD_MPLS argument.\n"]
7043 pub fn push_add_mpls(mut self, value: OvsActionAddMpls) -> Self {
7044 push_header(self.as_vec_mut(), 22u16, value.as_slice().len() as u16);
7045 self.as_vec_mut().extend(value.as_slice());
7046 self
7047 }
7048 pub fn nested_dec_ttl(mut self) -> PushDecTtlAttrs<Self> {
7049 let header_offset = push_nested_header(self.as_vec_mut(), 23u16);
7050 PushDecTtlAttrs {
7051 prev: Some(self),
7052 header_offset: Some(header_offset),
7053 }
7054 }
7055 #[doc = "Sends a packet sample to psample for external observation.\n"]
7056 pub fn nested_psample(mut self) -> PushPsampleAttrs<Self> {
7057 let header_offset = push_nested_header(self.as_vec_mut(), 24u16);
7058 PushPsampleAttrs {
7059 prev: Some(self),
7060 header_offset: Some(header_offset),
7061 }
7062 }
7063}
7064impl<Prev: Pusher> Drop for PushActionAttrs<Prev> {
7065 fn drop(&mut self) {
7066 if let Some(prev) = &mut self.prev {
7067 if let Some(header_offset) = &self.header_offset {
7068 finalize_nested_header(prev.as_vec_mut(), *header_offset);
7069 }
7070 }
7071 }
7072}
7073pub struct PushTunnelKeyAttrs<Prev: Pusher> {
7074 pub(crate) prev: Option<Prev>,
7075 pub(crate) header_offset: Option<usize>,
7076}
7077impl<Prev: Pusher> Pusher for PushTunnelKeyAttrs<Prev> {
7078 fn as_vec_mut(&mut self) -> &mut Vec<u8> {
7079 self.prev.as_mut().unwrap().as_vec_mut()
7080 }
7081 fn as_vec(&self) -> &Vec<u8> {
7082 self.prev.as_ref().unwrap().as_vec()
7083 }
7084}
7085impl<Prev: Pusher> PushTunnelKeyAttrs<Prev> {
7086 pub fn new(prev: Prev) -> Self {
7087 Self {
7088 prev: Some(prev),
7089 header_offset: None,
7090 }
7091 }
7092 pub fn end_nested(mut self) -> Prev {
7093 let mut prev = self.prev.take().unwrap();
7094 if let Some(header_offset) = &self.header_offset {
7095 finalize_nested_header(prev.as_vec_mut(), *header_offset);
7096 }
7097 prev
7098 }
7099 pub fn push_id(mut self, value: u64) -> Self {
7100 push_header(self.as_vec_mut(), 0u16, 8 as u16);
7101 self.as_vec_mut().extend(value.to_be_bytes());
7102 self
7103 }
7104 pub fn push_ipv4_src(mut self, value: u32) -> Self {
7105 push_header(self.as_vec_mut(), 1u16, 4 as u16);
7106 self.as_vec_mut().extend(value.to_be_bytes());
7107 self
7108 }
7109 pub fn push_ipv4_dst(mut self, value: u32) -> Self {
7110 push_header(self.as_vec_mut(), 2u16, 4 as u16);
7111 self.as_vec_mut().extend(value.to_be_bytes());
7112 self
7113 }
7114 pub fn push_tos(mut self, value: u8) -> Self {
7115 push_header(self.as_vec_mut(), 3u16, 1 as u16);
7116 self.as_vec_mut().extend(value.to_ne_bytes());
7117 self
7118 }
7119 pub fn push_ttl(mut self, value: u8) -> Self {
7120 push_header(self.as_vec_mut(), 4u16, 1 as u16);
7121 self.as_vec_mut().extend(value.to_ne_bytes());
7122 self
7123 }
7124 pub fn push_dont_fragment(mut self, value: ()) -> Self {
7125 push_header(self.as_vec_mut(), 5u16, 0 as u16);
7126 self
7127 }
7128 pub fn push_csum(mut self, value: ()) -> Self {
7129 push_header(self.as_vec_mut(), 6u16, 0 as u16);
7130 self
7131 }
7132 pub fn push_oam(mut self, value: ()) -> Self {
7133 push_header(self.as_vec_mut(), 7u16, 0 as u16);
7134 self
7135 }
7136 pub fn push_geneve_opts(mut self, value: &[u8]) -> Self {
7137 push_header(self.as_vec_mut(), 8u16, value.len() as u16);
7138 self.as_vec_mut().extend(value);
7139 self
7140 }
7141 pub fn push_tp_src(mut self, value: u16) -> Self {
7142 push_header(self.as_vec_mut(), 9u16, 2 as u16);
7143 self.as_vec_mut().extend(value.to_be_bytes());
7144 self
7145 }
7146 pub fn push_tp_dst(mut self, value: u16) -> Self {
7147 push_header(self.as_vec_mut(), 10u16, 2 as u16);
7148 self.as_vec_mut().extend(value.to_be_bytes());
7149 self
7150 }
7151 pub fn nested_vxlan_opts(mut self) -> PushVxlanExtAttrs<Self> {
7152 let header_offset = push_nested_header(self.as_vec_mut(), 11u16);
7153 PushVxlanExtAttrs {
7154 prev: Some(self),
7155 header_offset: Some(header_offset),
7156 }
7157 }
7158 #[doc = "struct in6_addr source IPv6 address\n"]
7159 pub fn push_ipv6_src(mut self, value: &[u8]) -> Self {
7160 push_header(self.as_vec_mut(), 12u16, value.len() as u16);
7161 self.as_vec_mut().extend(value);
7162 self
7163 }
7164 #[doc = "struct in6_addr destination IPv6 address\n"]
7165 pub fn push_ipv6_dst(mut self, value: &[u8]) -> Self {
7166 push_header(self.as_vec_mut(), 13u16, value.len() as u16);
7167 self.as_vec_mut().extend(value);
7168 self
7169 }
7170 pub fn push_pad(mut self, value: &[u8]) -> Self {
7171 push_header(self.as_vec_mut(), 14u16, value.len() as u16);
7172 self.as_vec_mut().extend(value);
7173 self
7174 }
7175 #[doc = "struct erspan_metadata\n"]
7176 pub fn push_erspan_opts(mut self, value: &[u8]) -> Self {
7177 push_header(self.as_vec_mut(), 15u16, value.len() as u16);
7178 self.as_vec_mut().extend(value);
7179 self
7180 }
7181 pub fn push_ipv4_info_bridge(mut self, value: ()) -> Self {
7182 push_header(self.as_vec_mut(), 16u16, 0 as u16);
7183 self
7184 }
7185}
7186impl<Prev: Pusher> Drop for PushTunnelKeyAttrs<Prev> {
7187 fn drop(&mut self) {
7188 if let Some(prev) = &mut self.prev {
7189 if let Some(header_offset) = &self.header_offset {
7190 finalize_nested_header(prev.as_vec_mut(), *header_offset);
7191 }
7192 }
7193 }
7194}
7195pub struct PushCheckPktLenAttrs<Prev: Pusher> {
7196 pub(crate) prev: Option<Prev>,
7197 pub(crate) header_offset: Option<usize>,
7198}
7199impl<Prev: Pusher> Pusher for PushCheckPktLenAttrs<Prev> {
7200 fn as_vec_mut(&mut self) -> &mut Vec<u8> {
7201 self.prev.as_mut().unwrap().as_vec_mut()
7202 }
7203 fn as_vec(&self) -> &Vec<u8> {
7204 self.prev.as_ref().unwrap().as_vec()
7205 }
7206}
7207impl<Prev: Pusher> PushCheckPktLenAttrs<Prev> {
7208 pub fn new(prev: Prev) -> Self {
7209 Self {
7210 prev: Some(prev),
7211 header_offset: None,
7212 }
7213 }
7214 pub fn end_nested(mut self) -> Prev {
7215 let mut prev = self.prev.take().unwrap();
7216 if let Some(header_offset) = &self.header_offset {
7217 finalize_nested_header(prev.as_vec_mut(), *header_offset);
7218 }
7219 prev
7220 }
7221 pub fn push_pkt_len(mut self, value: u16) -> Self {
7222 push_header(self.as_vec_mut(), 1u16, 2 as u16);
7223 self.as_vec_mut().extend(value.to_ne_bytes());
7224 self
7225 }
7226 pub fn nested_actions_if_greater(mut self) -> PushActionAttrs<Self> {
7227 let header_offset = push_nested_header(self.as_vec_mut(), 2u16);
7228 PushActionAttrs {
7229 prev: Some(self),
7230 header_offset: Some(header_offset),
7231 }
7232 }
7233 pub fn nested_actions_if_less_equal(mut self) -> PushActionAttrs<Self> {
7234 let header_offset = push_nested_header(self.as_vec_mut(), 3u16);
7235 PushActionAttrs {
7236 prev: Some(self),
7237 header_offset: Some(header_offset),
7238 }
7239 }
7240}
7241impl<Prev: Pusher> Drop for PushCheckPktLenAttrs<Prev> {
7242 fn drop(&mut self) {
7243 if let Some(prev) = &mut self.prev {
7244 if let Some(header_offset) = &self.header_offset {
7245 finalize_nested_header(prev.as_vec_mut(), *header_offset);
7246 }
7247 }
7248 }
7249}
7250pub struct PushSampleAttrs<Prev: Pusher> {
7251 pub(crate) prev: Option<Prev>,
7252 pub(crate) header_offset: Option<usize>,
7253}
7254impl<Prev: Pusher> Pusher for PushSampleAttrs<Prev> {
7255 fn as_vec_mut(&mut self) -> &mut Vec<u8> {
7256 self.prev.as_mut().unwrap().as_vec_mut()
7257 }
7258 fn as_vec(&self) -> &Vec<u8> {
7259 self.prev.as_ref().unwrap().as_vec()
7260 }
7261}
7262impl<Prev: Pusher> PushSampleAttrs<Prev> {
7263 pub fn new(prev: Prev) -> Self {
7264 Self {
7265 prev: Some(prev),
7266 header_offset: None,
7267 }
7268 }
7269 pub fn end_nested(mut self) -> Prev {
7270 let mut prev = self.prev.take().unwrap();
7271 if let Some(header_offset) = &self.header_offset {
7272 finalize_nested_header(prev.as_vec_mut(), *header_offset);
7273 }
7274 prev
7275 }
7276 pub fn push_probability(mut self, value: u32) -> Self {
7277 push_header(self.as_vec_mut(), 1u16, 4 as u16);
7278 self.as_vec_mut().extend(value.to_ne_bytes());
7279 self
7280 }
7281 pub fn nested_actions(mut self) -> PushActionAttrs<Self> {
7282 let header_offset = push_nested_header(self.as_vec_mut(), 2u16);
7283 PushActionAttrs {
7284 prev: Some(self),
7285 header_offset: Some(header_offset),
7286 }
7287 }
7288}
7289impl<Prev: Pusher> Drop for PushSampleAttrs<Prev> {
7290 fn drop(&mut self) {
7291 if let Some(prev) = &mut self.prev {
7292 if let Some(header_offset) = &self.header_offset {
7293 finalize_nested_header(prev.as_vec_mut(), *header_offset);
7294 }
7295 }
7296 }
7297}
7298pub struct PushUserspaceAttrs<Prev: Pusher> {
7299 pub(crate) prev: Option<Prev>,
7300 pub(crate) header_offset: Option<usize>,
7301}
7302impl<Prev: Pusher> Pusher for PushUserspaceAttrs<Prev> {
7303 fn as_vec_mut(&mut self) -> &mut Vec<u8> {
7304 self.prev.as_mut().unwrap().as_vec_mut()
7305 }
7306 fn as_vec(&self) -> &Vec<u8> {
7307 self.prev.as_ref().unwrap().as_vec()
7308 }
7309}
7310impl<Prev: Pusher> PushUserspaceAttrs<Prev> {
7311 pub fn new(prev: Prev) -> Self {
7312 Self {
7313 prev: Some(prev),
7314 header_offset: None,
7315 }
7316 }
7317 pub fn end_nested(mut self) -> Prev {
7318 let mut prev = self.prev.take().unwrap();
7319 if let Some(header_offset) = &self.header_offset {
7320 finalize_nested_header(prev.as_vec_mut(), *header_offset);
7321 }
7322 prev
7323 }
7324 pub fn push_pid(mut self, value: u32) -> Self {
7325 push_header(self.as_vec_mut(), 1u16, 4 as u16);
7326 self.as_vec_mut().extend(value.to_ne_bytes());
7327 self
7328 }
7329 pub fn push_userdata(mut self, value: &[u8]) -> Self {
7330 push_header(self.as_vec_mut(), 2u16, value.len() as u16);
7331 self.as_vec_mut().extend(value);
7332 self
7333 }
7334 pub fn push_egress_tun_port(mut self, value: u32) -> Self {
7335 push_header(self.as_vec_mut(), 3u16, 4 as u16);
7336 self.as_vec_mut().extend(value.to_ne_bytes());
7337 self
7338 }
7339 pub fn push_actions(mut self, value: ()) -> Self {
7340 push_header(self.as_vec_mut(), 4u16, 0 as u16);
7341 self
7342 }
7343}
7344impl<Prev: Pusher> Drop for PushUserspaceAttrs<Prev> {
7345 fn drop(&mut self) {
7346 if let Some(prev) = &mut self.prev {
7347 if let Some(header_offset) = &self.header_offset {
7348 finalize_nested_header(prev.as_vec_mut(), *header_offset);
7349 }
7350 }
7351 }
7352}
7353pub struct PushOvsNshKeyAttrs<Prev: Pusher> {
7354 pub(crate) prev: Option<Prev>,
7355 pub(crate) header_offset: Option<usize>,
7356}
7357impl<Prev: Pusher> Pusher for PushOvsNshKeyAttrs<Prev> {
7358 fn as_vec_mut(&mut self) -> &mut Vec<u8> {
7359 self.prev.as_mut().unwrap().as_vec_mut()
7360 }
7361 fn as_vec(&self) -> &Vec<u8> {
7362 self.prev.as_ref().unwrap().as_vec()
7363 }
7364}
7365impl<Prev: Pusher> PushOvsNshKeyAttrs<Prev> {
7366 pub fn new(prev: Prev) -> Self {
7367 Self {
7368 prev: Some(prev),
7369 header_offset: None,
7370 }
7371 }
7372 pub fn end_nested(mut self) -> Prev {
7373 let mut prev = self.prev.take().unwrap();
7374 if let Some(header_offset) = &self.header_offset {
7375 finalize_nested_header(prev.as_vec_mut(), *header_offset);
7376 }
7377 prev
7378 }
7379 pub fn push_base(mut self, value: &[u8]) -> Self {
7380 push_header(self.as_vec_mut(), 1u16, value.len() as u16);
7381 self.as_vec_mut().extend(value);
7382 self
7383 }
7384 pub fn push_md1(mut self, value: &[u8]) -> Self {
7385 push_header(self.as_vec_mut(), 2u16, value.len() as u16);
7386 self.as_vec_mut().extend(value);
7387 self
7388 }
7389 pub fn push_md2(mut self, value: &[u8]) -> Self {
7390 push_header(self.as_vec_mut(), 3u16, value.len() as u16);
7391 self.as_vec_mut().extend(value);
7392 self
7393 }
7394}
7395impl<Prev: Pusher> Drop for PushOvsNshKeyAttrs<Prev> {
7396 fn drop(&mut self) {
7397 if let Some(prev) = &mut self.prev {
7398 if let Some(header_offset) = &self.header_offset {
7399 finalize_nested_header(prev.as_vec_mut(), *header_offset);
7400 }
7401 }
7402 }
7403}
7404pub struct PushCtAttrs<Prev: Pusher> {
7405 pub(crate) prev: Option<Prev>,
7406 pub(crate) header_offset: Option<usize>,
7407}
7408impl<Prev: Pusher> Pusher for PushCtAttrs<Prev> {
7409 fn as_vec_mut(&mut self) -> &mut Vec<u8> {
7410 self.prev.as_mut().unwrap().as_vec_mut()
7411 }
7412 fn as_vec(&self) -> &Vec<u8> {
7413 self.prev.as_ref().unwrap().as_vec()
7414 }
7415}
7416impl<Prev: Pusher> PushCtAttrs<Prev> {
7417 pub fn new(prev: Prev) -> Self {
7418 Self {
7419 prev: Some(prev),
7420 header_offset: None,
7421 }
7422 }
7423 pub fn end_nested(mut self) -> Prev {
7424 let mut prev = self.prev.take().unwrap();
7425 if let Some(header_offset) = &self.header_offset {
7426 finalize_nested_header(prev.as_vec_mut(), *header_offset);
7427 }
7428 prev
7429 }
7430 pub fn push_commit(mut self, value: ()) -> Self {
7431 push_header(self.as_vec_mut(), 1u16, 0 as u16);
7432 self
7433 }
7434 pub fn push_zone(mut self, value: u16) -> Self {
7435 push_header(self.as_vec_mut(), 2u16, 2 as u16);
7436 self.as_vec_mut().extend(value.to_ne_bytes());
7437 self
7438 }
7439 pub fn push_mark(mut self, value: &[u8]) -> Self {
7440 push_header(self.as_vec_mut(), 3u16, value.len() as u16);
7441 self.as_vec_mut().extend(value);
7442 self
7443 }
7444 pub fn push_labels(mut self, value: &[u8]) -> Self {
7445 push_header(self.as_vec_mut(), 4u16, value.len() as u16);
7446 self.as_vec_mut().extend(value);
7447 self
7448 }
7449 pub fn push_helper(mut self, value: &CStr) -> Self {
7450 push_header(
7451 self.as_vec_mut(),
7452 5u16,
7453 value.to_bytes_with_nul().len() as u16,
7454 );
7455 self.as_vec_mut().extend(value.to_bytes_with_nul());
7456 self
7457 }
7458 pub fn push_helper_bytes(mut self, value: &[u8]) -> Self {
7459 push_header(self.as_vec_mut(), 5u16, (value.len() + 1) as u16);
7460 self.as_vec_mut().extend(value);
7461 self.as_vec_mut().push(0);
7462 self
7463 }
7464 pub fn nested_nat(mut self) -> PushNatAttrs<Self> {
7465 let header_offset = push_nested_header(self.as_vec_mut(), 6u16);
7466 PushNatAttrs {
7467 prev: Some(self),
7468 header_offset: Some(header_offset),
7469 }
7470 }
7471 pub fn push_force_commit(mut self, value: ()) -> Self {
7472 push_header(self.as_vec_mut(), 7u16, 0 as u16);
7473 self
7474 }
7475 pub fn push_eventmask(mut self, value: u32) -> Self {
7476 push_header(self.as_vec_mut(), 8u16, 4 as u16);
7477 self.as_vec_mut().extend(value.to_ne_bytes());
7478 self
7479 }
7480 pub fn push_timeout(mut self, value: &CStr) -> Self {
7481 push_header(
7482 self.as_vec_mut(),
7483 9u16,
7484 value.to_bytes_with_nul().len() as u16,
7485 );
7486 self.as_vec_mut().extend(value.to_bytes_with_nul());
7487 self
7488 }
7489 pub fn push_timeout_bytes(mut self, value: &[u8]) -> Self {
7490 push_header(self.as_vec_mut(), 9u16, (value.len() + 1) as u16);
7491 self.as_vec_mut().extend(value);
7492 self.as_vec_mut().push(0);
7493 self
7494 }
7495}
7496impl<Prev: Pusher> Drop for PushCtAttrs<Prev> {
7497 fn drop(&mut self) {
7498 if let Some(prev) = &mut self.prev {
7499 if let Some(header_offset) = &self.header_offset {
7500 finalize_nested_header(prev.as_vec_mut(), *header_offset);
7501 }
7502 }
7503 }
7504}
7505pub struct PushNatAttrs<Prev: Pusher> {
7506 pub(crate) prev: Option<Prev>,
7507 pub(crate) header_offset: Option<usize>,
7508}
7509impl<Prev: Pusher> Pusher for PushNatAttrs<Prev> {
7510 fn as_vec_mut(&mut self) -> &mut Vec<u8> {
7511 self.prev.as_mut().unwrap().as_vec_mut()
7512 }
7513 fn as_vec(&self) -> &Vec<u8> {
7514 self.prev.as_ref().unwrap().as_vec()
7515 }
7516}
7517impl<Prev: Pusher> PushNatAttrs<Prev> {
7518 pub fn new(prev: Prev) -> Self {
7519 Self {
7520 prev: Some(prev),
7521 header_offset: None,
7522 }
7523 }
7524 pub fn end_nested(mut self) -> Prev {
7525 let mut prev = self.prev.take().unwrap();
7526 if let Some(header_offset) = &self.header_offset {
7527 finalize_nested_header(prev.as_vec_mut(), *header_offset);
7528 }
7529 prev
7530 }
7531 pub fn push_src(mut self, value: ()) -> Self {
7532 push_header(self.as_vec_mut(), 1u16, 0 as u16);
7533 self
7534 }
7535 pub fn push_dst(mut self, value: ()) -> Self {
7536 push_header(self.as_vec_mut(), 2u16, 0 as u16);
7537 self
7538 }
7539 pub fn push_ip_min(mut self, value: &[u8]) -> Self {
7540 push_header(self.as_vec_mut(), 3u16, value.len() as u16);
7541 self.as_vec_mut().extend(value);
7542 self
7543 }
7544 pub fn push_ip_max(mut self, value: &[u8]) -> Self {
7545 push_header(self.as_vec_mut(), 4u16, value.len() as u16);
7546 self.as_vec_mut().extend(value);
7547 self
7548 }
7549 pub fn push_proto_min(mut self, value: u16) -> Self {
7550 push_header(self.as_vec_mut(), 5u16, 2 as u16);
7551 self.as_vec_mut().extend(value.to_ne_bytes());
7552 self
7553 }
7554 pub fn push_proto_max(mut self, value: u16) -> Self {
7555 push_header(self.as_vec_mut(), 6u16, 2 as u16);
7556 self.as_vec_mut().extend(value.to_ne_bytes());
7557 self
7558 }
7559 pub fn push_persistent(mut self, value: ()) -> Self {
7560 push_header(self.as_vec_mut(), 7u16, 0 as u16);
7561 self
7562 }
7563 pub fn push_proto_hash(mut self, value: ()) -> Self {
7564 push_header(self.as_vec_mut(), 8u16, 0 as u16);
7565 self
7566 }
7567 pub fn push_proto_random(mut self, value: ()) -> Self {
7568 push_header(self.as_vec_mut(), 9u16, 0 as u16);
7569 self
7570 }
7571}
7572impl<Prev: Pusher> Drop for PushNatAttrs<Prev> {
7573 fn drop(&mut self) {
7574 if let Some(prev) = &mut self.prev {
7575 if let Some(header_offset) = &self.header_offset {
7576 finalize_nested_header(prev.as_vec_mut(), *header_offset);
7577 }
7578 }
7579 }
7580}
7581pub struct PushDecTtlAttrs<Prev: Pusher> {
7582 pub(crate) prev: Option<Prev>,
7583 pub(crate) header_offset: Option<usize>,
7584}
7585impl<Prev: Pusher> Pusher for PushDecTtlAttrs<Prev> {
7586 fn as_vec_mut(&mut self) -> &mut Vec<u8> {
7587 self.prev.as_mut().unwrap().as_vec_mut()
7588 }
7589 fn as_vec(&self) -> &Vec<u8> {
7590 self.prev.as_ref().unwrap().as_vec()
7591 }
7592}
7593impl<Prev: Pusher> PushDecTtlAttrs<Prev> {
7594 pub fn new(prev: Prev) -> Self {
7595 Self {
7596 prev: Some(prev),
7597 header_offset: None,
7598 }
7599 }
7600 pub fn end_nested(mut self) -> Prev {
7601 let mut prev = self.prev.take().unwrap();
7602 if let Some(header_offset) = &self.header_offset {
7603 finalize_nested_header(prev.as_vec_mut(), *header_offset);
7604 }
7605 prev
7606 }
7607 pub fn nested_action(mut self) -> PushActionAttrs<Self> {
7608 let header_offset = push_nested_header(self.as_vec_mut(), 1u16);
7609 PushActionAttrs {
7610 prev: Some(self),
7611 header_offset: Some(header_offset),
7612 }
7613 }
7614}
7615impl<Prev: Pusher> Drop for PushDecTtlAttrs<Prev> {
7616 fn drop(&mut self) {
7617 if let Some(prev) = &mut self.prev {
7618 if let Some(header_offset) = &self.header_offset {
7619 finalize_nested_header(prev.as_vec_mut(), *header_offset);
7620 }
7621 }
7622 }
7623}
7624pub struct PushVxlanExtAttrs<Prev: Pusher> {
7625 pub(crate) prev: Option<Prev>,
7626 pub(crate) header_offset: Option<usize>,
7627}
7628impl<Prev: Pusher> Pusher for PushVxlanExtAttrs<Prev> {
7629 fn as_vec_mut(&mut self) -> &mut Vec<u8> {
7630 self.prev.as_mut().unwrap().as_vec_mut()
7631 }
7632 fn as_vec(&self) -> &Vec<u8> {
7633 self.prev.as_ref().unwrap().as_vec()
7634 }
7635}
7636impl<Prev: Pusher> PushVxlanExtAttrs<Prev> {
7637 pub fn new(prev: Prev) -> Self {
7638 Self {
7639 prev: Some(prev),
7640 header_offset: None,
7641 }
7642 }
7643 pub fn end_nested(mut self) -> Prev {
7644 let mut prev = self.prev.take().unwrap();
7645 if let Some(header_offset) = &self.header_offset {
7646 finalize_nested_header(prev.as_vec_mut(), *header_offset);
7647 }
7648 prev
7649 }
7650 pub fn push_gbp(mut self, value: u32) -> Self {
7651 push_header(self.as_vec_mut(), 1u16, 4 as u16);
7652 self.as_vec_mut().extend(value.to_ne_bytes());
7653 self
7654 }
7655}
7656impl<Prev: Pusher> Drop for PushVxlanExtAttrs<Prev> {
7657 fn drop(&mut self) {
7658 if let Some(prev) = &mut self.prev {
7659 if let Some(header_offset) = &self.header_offset {
7660 finalize_nested_header(prev.as_vec_mut(), *header_offset);
7661 }
7662 }
7663 }
7664}
7665pub struct PushPsampleAttrs<Prev: Pusher> {
7666 pub(crate) prev: Option<Prev>,
7667 pub(crate) header_offset: Option<usize>,
7668}
7669impl<Prev: Pusher> Pusher for PushPsampleAttrs<Prev> {
7670 fn as_vec_mut(&mut self) -> &mut Vec<u8> {
7671 self.prev.as_mut().unwrap().as_vec_mut()
7672 }
7673 fn as_vec(&self) -> &Vec<u8> {
7674 self.prev.as_ref().unwrap().as_vec()
7675 }
7676}
7677impl<Prev: Pusher> PushPsampleAttrs<Prev> {
7678 pub fn new(prev: Prev) -> Self {
7679 Self {
7680 prev: Some(prev),
7681 header_offset: None,
7682 }
7683 }
7684 pub fn end_nested(mut self) -> Prev {
7685 let mut prev = self.prev.take().unwrap();
7686 if let Some(header_offset) = &self.header_offset {
7687 finalize_nested_header(prev.as_vec_mut(), *header_offset);
7688 }
7689 prev
7690 }
7691 pub fn push_group(mut self, value: u32) -> Self {
7692 push_header(self.as_vec_mut(), 1u16, 4 as u16);
7693 self.as_vec_mut().extend(value.to_ne_bytes());
7694 self
7695 }
7696 pub fn push_cookie(mut self, value: &[u8]) -> Self {
7697 push_header(self.as_vec_mut(), 2u16, value.len() as u16);
7698 self.as_vec_mut().extend(value);
7699 self
7700 }
7701}
7702impl<Prev: Pusher> Drop for PushPsampleAttrs<Prev> {
7703 fn drop(&mut self) {
7704 if let Some(prev) = &mut self.prev {
7705 if let Some(header_offset) = &self.header_offset {
7706 finalize_nested_header(prev.as_vec_mut(), *header_offset);
7707 }
7708 }
7709 }
7710}
7711pub struct NotifGroup;
7712impl NotifGroup {
7713 pub const OVS_FLOW: &str = "ovs_flow";
7714 pub const OVS_FLOW_CSTR: &CStr = c"ovs_flow";
7715}
7716#[doc = "Get / dump OVS flow configuration and state\n\nRequest attributes:\n- [.nested_key()](PushFlowAttrs::nested_key)\n- [.push_ufid()](PushFlowAttrs::push_ufid)\n- [.push_ufid_flags()](PushFlowAttrs::push_ufid_flags)\n\nReply attributes:\n- [.get_key()](IterableFlowAttrs::get_key)\n- [.get_actions()](IterableFlowAttrs::get_actions)\n- [.get_stats()](IterableFlowAttrs::get_stats)\n- [.get_mask()](IterableFlowAttrs::get_mask)\n- [.get_ufid()](IterableFlowAttrs::get_ufid)\n\n"]
7717#[derive(Debug)]
7718pub struct OpGetDump<'r> {
7719 request: Request<'r>,
7720}
7721impl<'r> OpGetDump<'r> {
7722 pub fn new(mut request: Request<'r>, header: &OvsHeader) -> Self {
7723 Self::write_header(request.buf_mut(), header);
7724 Self {
7725 request: request.set_dump(),
7726 }
7727 }
7728 pub fn encode_request<'buf>(
7729 buf: &'buf mut Vec<u8>,
7730 header: &OvsHeader,
7731 ) -> PushFlowAttrs<&'buf mut Vec<u8>> {
7732 Self::write_header(buf, header);
7733 PushFlowAttrs::new(buf)
7734 }
7735 pub fn encode(&mut self) -> PushFlowAttrs<&mut Vec<u8>> {
7736 PushFlowAttrs::new(self.request.buf_mut())
7737 }
7738 pub fn into_encoder(self) -> PushFlowAttrs<RequestBuf<'r>> {
7739 PushFlowAttrs::new(self.request.buf)
7740 }
7741 pub fn decode_request<'a>(buf: &'a [u8]) -> (OvsHeader, IterableFlowAttrs<'a>) {
7742 let (header, attrs) = buf.split_at(buf.len().min(OvsHeader::len()));
7743 (
7744 OvsHeader::new_from_slice(header).unwrap_or_default(),
7745 IterableFlowAttrs::with_loc(attrs, buf.as_ptr() as usize),
7746 )
7747 }
7748 fn write_header<Prev: Pusher>(prev: &mut Prev, header: &OvsHeader) {
7749 prev.as_vec_mut().extend(header.as_slice());
7750 }
7751}
7752impl NetlinkRequest for OpGetDump<'_> {
7753 fn protocol(&self) -> Protocol {
7754 Protocol::Generic("ovs_flow".as_bytes())
7755 }
7756 fn flags(&self) -> u16 {
7757 self.request.flags
7758 }
7759 fn payload(&self) -> &[u8] {
7760 self.request.buf()
7761 }
7762 type ReplyType<'buf> = (OvsHeader, IterableFlowAttrs<'buf>);
7763 fn decode_reply<'buf>(buf: &'buf [u8]) -> Self::ReplyType<'buf> {
7764 Self::decode_request(buf)
7765 }
7766 fn lookup(
7767 buf: &[u8],
7768 offset: usize,
7769 missing_type: Option<u16>,
7770 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
7771 Self::decode_request(buf)
7772 .1
7773 .lookup_attr(offset, missing_type)
7774 }
7775}
7776#[doc = "Get / dump OVS flow configuration and state\n\nRequest attributes:\n- [.nested_key()](PushFlowAttrs::nested_key)\n- [.push_ufid()](PushFlowAttrs::push_ufid)\n- [.push_ufid_flags()](PushFlowAttrs::push_ufid_flags)\n\nReply attributes:\n- [.get_key()](IterableFlowAttrs::get_key)\n- [.get_actions()](IterableFlowAttrs::get_actions)\n- [.get_stats()](IterableFlowAttrs::get_stats)\n- [.get_mask()](IterableFlowAttrs::get_mask)\n- [.get_ufid()](IterableFlowAttrs::get_ufid)\n\n"]
7777#[derive(Debug)]
7778pub struct OpGetDo<'r> {
7779 request: Request<'r>,
7780}
7781impl<'r> OpGetDo<'r> {
7782 pub fn new(mut request: Request<'r>, header: &OvsHeader) -> Self {
7783 Self::write_header(request.buf_mut(), header);
7784 Self { request: request }
7785 }
7786 pub fn encode_request<'buf>(
7787 buf: &'buf mut Vec<u8>,
7788 header: &OvsHeader,
7789 ) -> PushFlowAttrs<&'buf mut Vec<u8>> {
7790 Self::write_header(buf, header);
7791 PushFlowAttrs::new(buf)
7792 }
7793 pub fn encode(&mut self) -> PushFlowAttrs<&mut Vec<u8>> {
7794 PushFlowAttrs::new(self.request.buf_mut())
7795 }
7796 pub fn into_encoder(self) -> PushFlowAttrs<RequestBuf<'r>> {
7797 PushFlowAttrs::new(self.request.buf)
7798 }
7799 pub fn decode_request<'a>(buf: &'a [u8]) -> (OvsHeader, IterableFlowAttrs<'a>) {
7800 let (header, attrs) = buf.split_at(buf.len().min(OvsHeader::len()));
7801 (
7802 OvsHeader::new_from_slice(header).unwrap_or_default(),
7803 IterableFlowAttrs::with_loc(attrs, buf.as_ptr() as usize),
7804 )
7805 }
7806 fn write_header<Prev: Pusher>(prev: &mut Prev, header: &OvsHeader) {
7807 prev.as_vec_mut().extend(header.as_slice());
7808 }
7809}
7810impl NetlinkRequest for OpGetDo<'_> {
7811 fn protocol(&self) -> Protocol {
7812 Protocol::Generic("ovs_flow".as_bytes())
7813 }
7814 fn flags(&self) -> u16 {
7815 self.request.flags
7816 }
7817 fn payload(&self) -> &[u8] {
7818 self.request.buf()
7819 }
7820 type ReplyType<'buf> = (OvsHeader, IterableFlowAttrs<'buf>);
7821 fn decode_reply<'buf>(buf: &'buf [u8]) -> Self::ReplyType<'buf> {
7822 Self::decode_request(buf)
7823 }
7824 fn lookup(
7825 buf: &[u8],
7826 offset: usize,
7827 missing_type: Option<u16>,
7828 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
7829 Self::decode_request(buf)
7830 .1
7831 .lookup_attr(offset, missing_type)
7832 }
7833}
7834#[doc = "Create OVS flow configuration in a data path\n\nRequest attributes:\n- [.nested_key()](PushFlowAttrs::nested_key)\n- [.nested_actions()](PushFlowAttrs::nested_actions)\n- [.nested_mask()](PushFlowAttrs::nested_mask)\n- [.push_ufid()](PushFlowAttrs::push_ufid)\n\n"]
7835#[derive(Debug)]
7836pub struct OpNewDo<'r> {
7837 request: Request<'r>,
7838}
7839impl<'r> OpNewDo<'r> {
7840 pub fn new(mut request: Request<'r>, header: &OvsHeader) -> Self {
7841 Self::write_header(request.buf_mut(), header);
7842 Self { request: request }
7843 }
7844 pub fn encode_request<'buf>(
7845 buf: &'buf mut Vec<u8>,
7846 header: &OvsHeader,
7847 ) -> PushFlowAttrs<&'buf mut Vec<u8>> {
7848 Self::write_header(buf, header);
7849 PushFlowAttrs::new(buf)
7850 }
7851 pub fn encode(&mut self) -> PushFlowAttrs<&mut Vec<u8>> {
7852 PushFlowAttrs::new(self.request.buf_mut())
7853 }
7854 pub fn into_encoder(self) -> PushFlowAttrs<RequestBuf<'r>> {
7855 PushFlowAttrs::new(self.request.buf)
7856 }
7857 pub fn decode_request<'a>(buf: &'a [u8]) -> (OvsHeader, IterableFlowAttrs<'a>) {
7858 let (header, attrs) = buf.split_at(buf.len().min(OvsHeader::len()));
7859 (
7860 OvsHeader::new_from_slice(header).unwrap_or_default(),
7861 IterableFlowAttrs::with_loc(attrs, buf.as_ptr() as usize),
7862 )
7863 }
7864 fn write_header<Prev: Pusher>(prev: &mut Prev, header: &OvsHeader) {
7865 prev.as_vec_mut().extend(header.as_slice());
7866 }
7867}
7868impl NetlinkRequest for OpNewDo<'_> {
7869 fn protocol(&self) -> Protocol {
7870 Protocol::Generic("ovs_flow".as_bytes())
7871 }
7872 fn flags(&self) -> u16 {
7873 self.request.flags
7874 }
7875 fn payload(&self) -> &[u8] {
7876 self.request.buf()
7877 }
7878 type ReplyType<'buf> = (OvsHeader, IterableFlowAttrs<'buf>);
7879 fn decode_reply<'buf>(buf: &'buf [u8]) -> Self::ReplyType<'buf> {
7880 Self::decode_request(buf)
7881 }
7882 fn lookup(
7883 buf: &[u8],
7884 offset: usize,
7885 missing_type: Option<u16>,
7886 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
7887 Self::decode_request(buf)
7888 .1
7889 .lookup_attr(offset, missing_type)
7890 }
7891}
7892use crate::traits::LookupFn;
7893use crate::utils::RequestBuf;
7894#[derive(Debug)]
7895pub struct Request<'buf> {
7896 buf: RequestBuf<'buf>,
7897 flags: u16,
7898 writeback: Option<&'buf mut Option<RequestInfo>>,
7899}
7900#[allow(unused)]
7901#[derive(Debug, Clone)]
7902pub struct RequestInfo {
7903 protocol: Protocol,
7904 flags: u16,
7905 name: &'static str,
7906 lookup: LookupFn,
7907}
7908impl Request<'static> {
7909 pub fn new() -> Self {
7910 Self::new_from_buf(Vec::new())
7911 }
7912 pub fn new_from_buf(buf: Vec<u8>) -> Self {
7913 Self {
7914 flags: 0,
7915 buf: RequestBuf::Own(buf),
7916 writeback: None,
7917 }
7918 }
7919 pub fn into_buf(self) -> Vec<u8> {
7920 match self.buf {
7921 RequestBuf::Own(buf) => buf,
7922 _ => unreachable!(),
7923 }
7924 }
7925}
7926impl<'buf> Request<'buf> {
7927 pub fn new_with_buf(buf: &'buf mut Vec<u8>) -> Self {
7928 buf.clear();
7929 Self::new_extend(buf)
7930 }
7931 pub fn new_extend(buf: &'buf mut Vec<u8>) -> Self {
7932 Self {
7933 flags: 0,
7934 buf: RequestBuf::Ref(buf),
7935 writeback: None,
7936 }
7937 }
7938 fn do_writeback(&mut self, protocol: Protocol, name: &'static str, lookup: LookupFn) {
7939 let Some(writeback) = &mut self.writeback else {
7940 return;
7941 };
7942 **writeback = Some(RequestInfo {
7943 protocol,
7944 flags: self.flags,
7945 name,
7946 lookup,
7947 })
7948 }
7949 pub fn buf(&self) -> &Vec<u8> {
7950 self.buf.buf()
7951 }
7952 pub fn buf_mut(&mut self) -> &mut Vec<u8> {
7953 self.buf.buf_mut()
7954 }
7955 #[doc = "Set `NLM_F_CREATE` flag"]
7956 pub fn set_create(mut self) -> Self {
7957 self.flags |= consts::NLM_F_CREATE as u16;
7958 self
7959 }
7960 #[doc = "Set `NLM_F_EXCL` flag"]
7961 pub fn set_excl(mut self) -> Self {
7962 self.flags |= consts::NLM_F_EXCL as u16;
7963 self
7964 }
7965 #[doc = "Set `NLM_F_REPLACE` flag"]
7966 pub fn set_replace(mut self) -> Self {
7967 self.flags |= consts::NLM_F_REPLACE as u16;
7968 self
7969 }
7970 #[doc = "Set `NLM_F_CREATE` and `NLM_F_REPLACE` flag"]
7971 pub fn set_change(self) -> Self {
7972 self.set_create().set_replace()
7973 }
7974 #[doc = "Set `NLM_F_APPEND` flag"]
7975 pub fn set_append(mut self) -> Self {
7976 self.flags |= consts::NLM_F_APPEND as u16;
7977 self
7978 }
7979 #[doc = "Set `self.flags |= flags`"]
7980 pub fn set_flags(mut self, flags: u16) -> Self {
7981 self.flags |= flags;
7982 self
7983 }
7984 #[doc = "Set `self.flags ^= self.flags & flags`"]
7985 pub fn unset_flags(mut self, flags: u16) -> Self {
7986 self.flags ^= self.flags & flags;
7987 self
7988 }
7989 #[doc = "Set `NLM_F_DUMP` flag"]
7990 fn set_dump(mut self) -> Self {
7991 self.flags |= consts::NLM_F_DUMP as u16;
7992 self
7993 }
7994 #[doc = "Get / dump OVS flow configuration and state\n\nRequest attributes:\n- [.nested_key()](PushFlowAttrs::nested_key)\n- [.push_ufid()](PushFlowAttrs::push_ufid)\n- [.push_ufid_flags()](PushFlowAttrs::push_ufid_flags)\n\nReply attributes:\n- [.get_key()](IterableFlowAttrs::get_key)\n- [.get_actions()](IterableFlowAttrs::get_actions)\n- [.get_stats()](IterableFlowAttrs::get_stats)\n- [.get_mask()](IterableFlowAttrs::get_mask)\n- [.get_ufid()](IterableFlowAttrs::get_ufid)\n\n"]
7995 pub fn op_get_dump(self, header: &OvsHeader) -> OpGetDump<'buf> {
7996 let mut res = OpGetDump::new(self, header);
7997 res.request
7998 .do_writeback(res.protocol(), "op-get-dump", OpGetDump::lookup);
7999 res
8000 }
8001 #[doc = "Get / dump OVS flow configuration and state\n\nRequest attributes:\n- [.nested_key()](PushFlowAttrs::nested_key)\n- [.push_ufid()](PushFlowAttrs::push_ufid)\n- [.push_ufid_flags()](PushFlowAttrs::push_ufid_flags)\n\nReply attributes:\n- [.get_key()](IterableFlowAttrs::get_key)\n- [.get_actions()](IterableFlowAttrs::get_actions)\n- [.get_stats()](IterableFlowAttrs::get_stats)\n- [.get_mask()](IterableFlowAttrs::get_mask)\n- [.get_ufid()](IterableFlowAttrs::get_ufid)\n\n"]
8002 pub fn op_get_do(self, header: &OvsHeader) -> OpGetDo<'buf> {
8003 let mut res = OpGetDo::new(self, header);
8004 res.request
8005 .do_writeback(res.protocol(), "op-get-do", OpGetDo::lookup);
8006 res
8007 }
8008 #[doc = "Create OVS flow configuration in a data path\n\nRequest attributes:\n- [.nested_key()](PushFlowAttrs::nested_key)\n- [.nested_actions()](PushFlowAttrs::nested_actions)\n- [.nested_mask()](PushFlowAttrs::nested_mask)\n- [.push_ufid()](PushFlowAttrs::push_ufid)\n\n"]
8009 pub fn op_new_do(self, header: &OvsHeader) -> OpNewDo<'buf> {
8010 let mut res = OpNewDo::new(self, header);
8011 res.request
8012 .do_writeback(res.protocol(), "op-new-do", OpNewDo::lookup);
8013 res
8014 }
8015}
8016#[cfg(test)]
8017mod generated_tests {
8018 use super::*;
8019 #[test]
8020 fn tests() {
8021 let _ = IterableFlowAttrs::get_actions;
8022 let _ = IterableFlowAttrs::get_key;
8023 let _ = IterableFlowAttrs::get_mask;
8024 let _ = IterableFlowAttrs::get_stats;
8025 let _ = IterableFlowAttrs::get_ufid;
8026 let _ = PushFlowAttrs::<&mut Vec<u8>>::nested_actions;
8027 let _ = PushFlowAttrs::<&mut Vec<u8>>::nested_key;
8028 let _ = PushFlowAttrs::<&mut Vec<u8>>::nested_mask;
8029 let _ = PushFlowAttrs::<&mut Vec<u8>>::push_ufid;
8030 let _ = PushFlowAttrs::<&mut Vec<u8>>::push_ufid_flags;
8031 }
8032}