1#![doc = "OVS flow configuration over generic netlink\\."]
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 = "Header for OVS Generic Netlink messages\\.\n"]
19#[doc = "Enum - defines an integer enumeration, with values for each entry incrementing by 1, (e.g. 0, 1, 2, 3)"]
20#[derive(Debug, Clone, Copy)]
21pub enum OvsFragType {
22 #[doc = "Packet is not a fragment\\."]
23 None = 0,
24 #[doc = "Packet is a fragment with offset 0\\."]
25 First = 1,
26 #[doc = "Packet is a fragment with nonzero offset\\."]
27 Later = 2,
28 Any = 255,
29}
30impl OvsFragType {
31 pub fn from_value(value: u64) -> Option<Self> {
32 Some(match value {
33 0 => Self::None,
34 1 => Self::First,
35 2 => Self::Later,
36 255 => Self::Any,
37 _ => return None,
38 })
39 }
40}
41#[doc = "Flags - defines an integer enumeration, with values for each entry occupying a bit, starting from bit 0, (e.g. 1, 2, 4, 8)"]
42#[derive(Debug, Clone, Copy)]
43pub enum OvsUfidFlags {
44 OmitKey = 1 << 0,
45 OmitMask = 1 << 1,
46 OmitActions = 1 << 2,
47}
48impl OvsUfidFlags {
49 pub fn from_value(value: u64) -> Option<Self> {
50 Some(match value {
51 n if n == 1 << 0 => Self::OmitKey,
52 n if n == 1 << 1 => Self::OmitMask,
53 n if n == 1 << 2 => Self::OmitActions,
54 _ => return None,
55 })
56 }
57}
58#[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\\. Each\ndatapath is free to use its own hash algorithm\\. The hash value will be\nopaque to the user space daemon\\.\n"]
59#[doc = "Enum - defines an integer enumeration, with values for each entry incrementing by 1, (e.g. 0, 1, 2, 3)"]
60#[derive(Debug, Clone, Copy)]
61pub enum OvsHashAlg {
62 OvsHashAlgL4 = 0,
63}
64impl OvsHashAlg {
65 pub fn from_value(value: u64) -> Option<Self> {
66 Some(match value {
67 0 => Self::OvsHashAlgL4,
68 _ => return None,
69 })
70 }
71}
72#[doc = "Flags - defines an integer enumeration, with values for each entry occupying a bit, starting from bit 0, (e.g. 1, 2, 4, 8)"]
73#[derive(Debug, Clone, Copy)]
74pub enum CtStateFlags {
75 #[doc = "Beginning of a new connection\\."]
76 New = 1 << 0,
77 #[doc = "Part of an existing connenction"]
78 Established = 1 << 1,
79 #[doc = "Related to an existing connection\\."]
80 Related = 1 << 2,
81 #[doc = "Flow is in the reply direction\\."]
82 ReplyDir = 1 << 3,
83 #[doc = "Could not track the connection\\."]
84 Invalid = 1 << 4,
85 #[doc = "Conntrack has occurred\\."]
86 Tracked = 1 << 5,
87 #[doc = "Packet's source address/port was mangled by NAT\\."]
88 SrcNat = 1 << 6,
89 #[doc = "Packet's destination address/port was mangled by NAT\\."]
90 DstNat = 1 << 7,
91}
92impl CtStateFlags {
93 pub fn from_value(value: u64) -> Option<Self> {
94 Some(match value {
95 n if n == 1 << 0 => Self::New,
96 n if n == 1 << 1 => Self::Established,
97 n if n == 1 << 2 => Self::Related,
98 n if n == 1 << 3 => Self::ReplyDir,
99 n if n == 1 << 4 => Self::Invalid,
100 n if n == 1 << 5 => Self::Tracked,
101 n if n == 1 << 6 => Self::SrcNat,
102 n if n == 1 << 7 => Self::DstNat,
103 _ => return None,
104 })
105 }
106}
107#[derive(Debug)]
108#[repr(C, packed(4))]
109pub struct OvsHeader {
110 #[doc = "ifindex of local port for datapath (0 to make a request not specific\nto a 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\\."]
177 pub n_packets: u64,
178 #[doc = "Number of matched bytes\\."]
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\\."]
1249 pub _vlan_tpid_be: u16,
1250 #[doc = "Tag control identifier (TCI) to push\\."]
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\\."]
1314 pub fn vlan_tpid(&self) -> u16 {
1315 u16::from_be(self._vlan_tpid_be)
1316 }
1317 #[doc = "Tag protocol identifier (TPID) to push\\."]
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\\."]
1322 pub fn vlan_tci(&self) -> u16 {
1323 u16::from_be(self._vlan_tci_be)
1324 }
1325 #[doc = "Tag control identifier (TCI) to push\\."]
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\\."]
1342 pub hash_alg: u32,
1343 #[doc = "Basis used for computing hash\\."]
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\nmatch the key\\. Always present in notifications\\. Required for\nOVS\\_FLOW\\_CMD\\_NEW requests, optional for OVS\\_FLOW\\_CMD\\_SET requests\\. An\nOVS\\_FLOW\\_CMD\\_SET without OVS\\_FLOW\\_ATTR\\_ACTIONS will not modify the\nactions\\. To clear the actions, an OVS\\_FLOW\\_ATTR\\_ACTIONS without any\nnested attributes must be given\\.\n"]
1600 Actions(IterableActionAttrs<'a>),
1601 #[doc = "Statistics for this flow\\. Present in notifications if the stats would\nbe nonzero\\. 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\nflow\\. Only present in notifications if a packet has been processed for\nthis flow\\. 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\nignored in requests\\. Never present in notifications\\.\n"]
1608 Clear(()),
1609 #[doc = "Nested attributes specifying the mask bits for wildcarded flow\nmatch\\. Mask bit value '1' specifies exact match with corresponding\nflow key bit, while mask bit value '0' specifies a wildcarded\nmatch\\. Omitting attribute is treated as wildcarding all corresponding\nfields\\. Optional for all requests\\. If not present, all flow key bits\nare exact match bits\\.\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\nflow\\. Causes the flow to be indexed by this value rather than the\nvalue of the OVS\\_FLOW\\_ATTR\\_KEY attribute\\. Optional for all\nrequests\\. Present in notifications if the flow was created with this\nattribute\\.\n"]
1614 Ufid(&'a [u8]),
1615 #[doc = "A 32\\-bit value of ORed flags that provide alternative semantics for\nflow installation 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 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\nmatch the key\\. Always present in notifications\\. Required for\nOVS\\_FLOW\\_CMD\\_NEW requests, optional for OVS\\_FLOW\\_CMD\\_SET requests\\. An\nOVS\\_FLOW\\_CMD\\_SET without OVS\\_FLOW\\_ATTR\\_ACTIONS will not modify the\nactions\\. To clear the actions, an OVS\\_FLOW\\_ATTR\\_ACTIONS without any\nnested attributes must be given\\.\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 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\nbe nonzero\\. 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 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 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\nflow\\. Only present in notifications if a packet has been processed for\nthis flow\\. 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 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\nignored in 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 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\nmatch\\. Mask bit value '1' specifies exact match with corresponding\nflow key bit, while mask bit value '0' specifies a wildcarded\nmatch\\. Omitting attribute is treated as wildcarding all corresponding\nfields\\. Optional for all requests\\. If not present, all flow key bits\nare exact match bits\\.\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 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 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\nflow\\. Causes the flow to be indexed by this value rather than the\nvalue of the OVS\\_FLOW\\_ATTR\\_KEY attribute\\. Optional for all\nrequests\\. Present in notifications if the flow was created with this\nattribute\\.\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 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\nflow installation 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 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 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 pos = self.pos;
1840 let mut r#type;
1841 loop {
1842 r#type = None;
1843 if self.buf.len() == self.pos {
1844 return None;
1845 }
1846 let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
1847 break;
1848 };
1849 r#type = Some(header.r#type);
1850 let res = match header.r#type {
1851 1u16 => FlowAttrs::Key({
1852 let res = Some(IterableKeyAttrs::with_loc(next, self.orig_loc));
1853 let Some(val) = res else { break };
1854 val
1855 }),
1856 2u16 => FlowAttrs::Actions({
1857 let res = Some(IterableActionAttrs::with_loc(next, self.orig_loc));
1858 let Some(val) = res else { break };
1859 val
1860 }),
1861 3u16 => FlowAttrs::Stats({
1862 let res = Some(OvsFlowStats::new_from_zeroed(next));
1863 let Some(val) = res else { break };
1864 val
1865 }),
1866 4u16 => FlowAttrs::TcpFlags({
1867 let res = parse_u8(next);
1868 let Some(val) = res else { break };
1869 val
1870 }),
1871 5u16 => FlowAttrs::Used({
1872 let res = parse_u64(next);
1873 let Some(val) = res else { break };
1874 val
1875 }),
1876 6u16 => FlowAttrs::Clear(()),
1877 7u16 => FlowAttrs::Mask({
1878 let res = Some(IterableKeyAttrs::with_loc(next, self.orig_loc));
1879 let Some(val) = res else { break };
1880 val
1881 }),
1882 8u16 => FlowAttrs::Probe({
1883 let res = Some(next);
1884 let Some(val) = res else { break };
1885 val
1886 }),
1887 9u16 => FlowAttrs::Ufid({
1888 let res = Some(next);
1889 let Some(val) = res else { break };
1890 val
1891 }),
1892 10u16 => FlowAttrs::UfidFlags({
1893 let res = parse_u32(next);
1894 let Some(val) = res else { break };
1895 val
1896 }),
1897 11u16 => FlowAttrs::Pad({
1898 let res = Some(next);
1899 let Some(val) = res else { break };
1900 val
1901 }),
1902 n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
1903 n => continue,
1904 };
1905 return Some(Ok(res));
1906 }
1907 Some(Err(ErrorContext::new(
1908 "FlowAttrs",
1909 r#type.and_then(|t| FlowAttrs::attr_from_type(t)),
1910 self.orig_loc,
1911 self.buf.as_ptr().wrapping_add(pos) as usize,
1912 )))
1913 }
1914}
1915impl<'a> std::fmt::Debug for IterableFlowAttrs<'_> {
1916 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1917 let mut fmt = f.debug_struct("FlowAttrs");
1918 for attr in self.clone() {
1919 let attr = match attr {
1920 Ok(a) => a,
1921 Err(err) => {
1922 fmt.finish()?;
1923 f.write_str("Err(")?;
1924 err.fmt(f)?;
1925 return f.write_str(")");
1926 }
1927 };
1928 match attr {
1929 FlowAttrs::Key(val) => fmt.field("Key", &val),
1930 FlowAttrs::Actions(val) => fmt.field("Actions", &val),
1931 FlowAttrs::Stats(val) => fmt.field("Stats", &val),
1932 FlowAttrs::TcpFlags(val) => fmt.field("TcpFlags", &val),
1933 FlowAttrs::Used(val) => fmt.field("Used", &val),
1934 FlowAttrs::Clear(val) => fmt.field("Clear", &val),
1935 FlowAttrs::Mask(val) => fmt.field("Mask", &val),
1936 FlowAttrs::Probe(val) => fmt.field("Probe", &val),
1937 FlowAttrs::Ufid(val) => fmt.field("Ufid", &val),
1938 FlowAttrs::UfidFlags(val) => fmt.field(
1939 "UfidFlags",
1940 &FormatFlags(val.into(), OvsUfidFlags::from_value),
1941 ),
1942 FlowAttrs::Pad(val) => fmt.field("Pad", &val),
1943 };
1944 }
1945 fmt.finish()
1946 }
1947}
1948impl IterableFlowAttrs<'_> {
1949 pub fn lookup_attr(
1950 &self,
1951 offset: usize,
1952 missing_type: Option<u16>,
1953 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
1954 let mut stack = Vec::new();
1955 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
1956 if missing_type.is_some() && cur == offset {
1957 stack.push(("FlowAttrs", offset));
1958 return (
1959 stack,
1960 missing_type.and_then(|t| FlowAttrs::attr_from_type(t)),
1961 );
1962 }
1963 if cur > offset || cur + self.buf.len() < offset {
1964 return (stack, None);
1965 }
1966 let mut attrs = self.clone();
1967 let mut last_off = cur + attrs.pos;
1968 let mut missing = None;
1969 while let Some(attr) = attrs.next() {
1970 let Ok(attr) = attr else { break };
1971 match attr {
1972 FlowAttrs::Key(val) => {
1973 (stack, missing) = val.lookup_attr(offset, missing_type);
1974 if !stack.is_empty() {
1975 break;
1976 }
1977 }
1978 FlowAttrs::Actions(val) => {
1979 (stack, missing) = val.lookup_attr(offset, missing_type);
1980 if !stack.is_empty() {
1981 break;
1982 }
1983 }
1984 FlowAttrs::Stats(val) => {
1985 if last_off == offset {
1986 stack.push(("Stats", last_off));
1987 break;
1988 }
1989 }
1990 FlowAttrs::TcpFlags(val) => {
1991 if last_off == offset {
1992 stack.push(("TcpFlags", last_off));
1993 break;
1994 }
1995 }
1996 FlowAttrs::Used(val) => {
1997 if last_off == offset {
1998 stack.push(("Used", last_off));
1999 break;
2000 }
2001 }
2002 FlowAttrs::Clear(val) => {
2003 if last_off == offset {
2004 stack.push(("Clear", last_off));
2005 break;
2006 }
2007 }
2008 FlowAttrs::Mask(val) => {
2009 (stack, missing) = val.lookup_attr(offset, missing_type);
2010 if !stack.is_empty() {
2011 break;
2012 }
2013 }
2014 FlowAttrs::Probe(val) => {
2015 if last_off == offset {
2016 stack.push(("Probe", last_off));
2017 break;
2018 }
2019 }
2020 FlowAttrs::Ufid(val) => {
2021 if last_off == offset {
2022 stack.push(("Ufid", last_off));
2023 break;
2024 }
2025 }
2026 FlowAttrs::UfidFlags(val) => {
2027 if last_off == offset {
2028 stack.push(("UfidFlags", last_off));
2029 break;
2030 }
2031 }
2032 FlowAttrs::Pad(val) => {
2033 if last_off == offset {
2034 stack.push(("Pad", last_off));
2035 break;
2036 }
2037 }
2038 _ => {}
2039 };
2040 last_off = cur + attrs.pos;
2041 }
2042 if !stack.is_empty() {
2043 stack.push(("FlowAttrs", cur));
2044 }
2045 (stack, missing)
2046 }
2047}
2048#[derive(Clone)]
2049pub enum KeyAttrs<'a> {
2050 Encap(IterableKeyAttrs<'a>),
2051 Priority(u32),
2052 InPort(u32),
2053 #[doc = "struct ovs\\_key\\_ethernet"]
2054 Ethernet(OvsKeyEthernet),
2055 Vlan(u16),
2056 Ethertype(u16),
2057 Ipv4(OvsKeyIpv4),
2058 #[doc = "struct ovs\\_key\\_ipv6"]
2059 Ipv6(OvsKeyIpv6),
2060 Tcp(OvsKeyTcp),
2061 Udp(OvsKeyUdp),
2062 Icmp(OvsKeyIcmp),
2063 Icmpv6(OvsKeyIcmp),
2064 #[doc = "struct ovs\\_key\\_arp"]
2065 Arp(OvsKeyArp),
2066 #[doc = "struct ovs\\_key\\_nd"]
2067 Nd(OvsKeyNd),
2068 SkbMark(u32),
2069 Tunnel(IterableTunnelKeyAttrs<'a>),
2070 Sctp(OvsKeySctp),
2071 TcpFlags(u16),
2072 #[doc = "Value 0 indicates the hash is not computed by the datapath\\."]
2073 DpHash(u32),
2074 RecircId(u32),
2075 Mpls(OvsKeyMpls),
2076 #[doc = "Associated type: [`CtStateFlags`] (1 bit per enumeration)"]
2077 CtState(u32),
2078 #[doc = "connection tracking zone"]
2079 CtZone(u16),
2080 #[doc = "connection tracking mark"]
2081 CtMark(u32),
2082 #[doc = "16\\-octet connection tracking label"]
2083 CtLabels(&'a [u8]),
2084 CtOrigTupleIpv4(OvsKeyCtTupleIpv4),
2085 #[doc = "struct ovs\\_key\\_ct\\_tuple\\_ipv6"]
2086 CtOrigTupleIpv6(&'a [u8]),
2087 Nsh(IterableOvsNshKeyAttrs<'a>),
2088 #[doc = "Should not be sent to the kernel"]
2089 PacketType(u32),
2090 #[doc = "Should not be sent to the kernel"]
2091 NdExtensions(&'a [u8]),
2092 #[doc = "struct ip\\_tunnel\\_info"]
2093 TunnelInfo(&'a [u8]),
2094 #[doc = "struct ovs\\_key\\_ipv6\\_exthdr"]
2095 Ipv6Exthdrs(OvsKeyIpv6Exthdrs),
2096}
2097impl<'a> IterableKeyAttrs<'a> {
2098 pub fn get_encap(&self) -> Result<IterableKeyAttrs<'a>, ErrorContext> {
2099 let mut iter = self.clone();
2100 iter.pos = 0;
2101 for attr in iter {
2102 if let KeyAttrs::Encap(val) = attr? {
2103 return Ok(val);
2104 }
2105 }
2106 Err(ErrorContext::new_missing(
2107 "KeyAttrs",
2108 "Encap",
2109 self.orig_loc,
2110 self.buf.as_ptr() as usize,
2111 ))
2112 }
2113 pub fn get_priority(&self) -> Result<u32, ErrorContext> {
2114 let mut iter = self.clone();
2115 iter.pos = 0;
2116 for attr in iter {
2117 if let KeyAttrs::Priority(val) = attr? {
2118 return Ok(val);
2119 }
2120 }
2121 Err(ErrorContext::new_missing(
2122 "KeyAttrs",
2123 "Priority",
2124 self.orig_loc,
2125 self.buf.as_ptr() as usize,
2126 ))
2127 }
2128 pub fn get_in_port(&self) -> Result<u32, ErrorContext> {
2129 let mut iter = self.clone();
2130 iter.pos = 0;
2131 for attr in iter {
2132 if let KeyAttrs::InPort(val) = attr? {
2133 return Ok(val);
2134 }
2135 }
2136 Err(ErrorContext::new_missing(
2137 "KeyAttrs",
2138 "InPort",
2139 self.orig_loc,
2140 self.buf.as_ptr() as usize,
2141 ))
2142 }
2143 #[doc = "struct ovs\\_key\\_ethernet"]
2144 pub fn get_ethernet(&self) -> Result<OvsKeyEthernet, ErrorContext> {
2145 let mut iter = self.clone();
2146 iter.pos = 0;
2147 for attr in iter {
2148 if let KeyAttrs::Ethernet(val) = attr? {
2149 return Ok(val);
2150 }
2151 }
2152 Err(ErrorContext::new_missing(
2153 "KeyAttrs",
2154 "Ethernet",
2155 self.orig_loc,
2156 self.buf.as_ptr() as usize,
2157 ))
2158 }
2159 pub fn get_vlan(&self) -> Result<u16, ErrorContext> {
2160 let mut iter = self.clone();
2161 iter.pos = 0;
2162 for attr in iter {
2163 if let KeyAttrs::Vlan(val) = attr? {
2164 return Ok(val);
2165 }
2166 }
2167 Err(ErrorContext::new_missing(
2168 "KeyAttrs",
2169 "Vlan",
2170 self.orig_loc,
2171 self.buf.as_ptr() as usize,
2172 ))
2173 }
2174 pub fn get_ethertype(&self) -> Result<u16, ErrorContext> {
2175 let mut iter = self.clone();
2176 iter.pos = 0;
2177 for attr in iter {
2178 if let KeyAttrs::Ethertype(val) = attr? {
2179 return Ok(val);
2180 }
2181 }
2182 Err(ErrorContext::new_missing(
2183 "KeyAttrs",
2184 "Ethertype",
2185 self.orig_loc,
2186 self.buf.as_ptr() as usize,
2187 ))
2188 }
2189 pub fn get_ipv4(&self) -> Result<OvsKeyIpv4, ErrorContext> {
2190 let mut iter = self.clone();
2191 iter.pos = 0;
2192 for attr in iter {
2193 if let KeyAttrs::Ipv4(val) = attr? {
2194 return Ok(val);
2195 }
2196 }
2197 Err(ErrorContext::new_missing(
2198 "KeyAttrs",
2199 "Ipv4",
2200 self.orig_loc,
2201 self.buf.as_ptr() as usize,
2202 ))
2203 }
2204 #[doc = "struct ovs\\_key\\_ipv6"]
2205 pub fn get_ipv6(&self) -> Result<OvsKeyIpv6, ErrorContext> {
2206 let mut iter = self.clone();
2207 iter.pos = 0;
2208 for attr in iter {
2209 if let KeyAttrs::Ipv6(val) = attr? {
2210 return Ok(val);
2211 }
2212 }
2213 Err(ErrorContext::new_missing(
2214 "KeyAttrs",
2215 "Ipv6",
2216 self.orig_loc,
2217 self.buf.as_ptr() as usize,
2218 ))
2219 }
2220 pub fn get_tcp(&self) -> Result<OvsKeyTcp, ErrorContext> {
2221 let mut iter = self.clone();
2222 iter.pos = 0;
2223 for attr in iter {
2224 if let KeyAttrs::Tcp(val) = attr? {
2225 return Ok(val);
2226 }
2227 }
2228 Err(ErrorContext::new_missing(
2229 "KeyAttrs",
2230 "Tcp",
2231 self.orig_loc,
2232 self.buf.as_ptr() as usize,
2233 ))
2234 }
2235 pub fn get_udp(&self) -> Result<OvsKeyUdp, ErrorContext> {
2236 let mut iter = self.clone();
2237 iter.pos = 0;
2238 for attr in iter {
2239 if let KeyAttrs::Udp(val) = attr? {
2240 return Ok(val);
2241 }
2242 }
2243 Err(ErrorContext::new_missing(
2244 "KeyAttrs",
2245 "Udp",
2246 self.orig_loc,
2247 self.buf.as_ptr() as usize,
2248 ))
2249 }
2250 pub fn get_icmp(&self) -> Result<OvsKeyIcmp, ErrorContext> {
2251 let mut iter = self.clone();
2252 iter.pos = 0;
2253 for attr in iter {
2254 if let KeyAttrs::Icmp(val) = attr? {
2255 return Ok(val);
2256 }
2257 }
2258 Err(ErrorContext::new_missing(
2259 "KeyAttrs",
2260 "Icmp",
2261 self.orig_loc,
2262 self.buf.as_ptr() as usize,
2263 ))
2264 }
2265 pub fn get_icmpv6(&self) -> Result<OvsKeyIcmp, ErrorContext> {
2266 let mut iter = self.clone();
2267 iter.pos = 0;
2268 for attr in iter {
2269 if let KeyAttrs::Icmpv6(val) = attr? {
2270 return Ok(val);
2271 }
2272 }
2273 Err(ErrorContext::new_missing(
2274 "KeyAttrs",
2275 "Icmpv6",
2276 self.orig_loc,
2277 self.buf.as_ptr() as usize,
2278 ))
2279 }
2280 #[doc = "struct ovs\\_key\\_arp"]
2281 pub fn get_arp(&self) -> Result<OvsKeyArp, ErrorContext> {
2282 let mut iter = self.clone();
2283 iter.pos = 0;
2284 for attr in iter {
2285 if let KeyAttrs::Arp(val) = attr? {
2286 return Ok(val);
2287 }
2288 }
2289 Err(ErrorContext::new_missing(
2290 "KeyAttrs",
2291 "Arp",
2292 self.orig_loc,
2293 self.buf.as_ptr() as usize,
2294 ))
2295 }
2296 #[doc = "struct ovs\\_key\\_nd"]
2297 pub fn get_nd(&self) -> Result<OvsKeyNd, ErrorContext> {
2298 let mut iter = self.clone();
2299 iter.pos = 0;
2300 for attr in iter {
2301 if let KeyAttrs::Nd(val) = attr? {
2302 return Ok(val);
2303 }
2304 }
2305 Err(ErrorContext::new_missing(
2306 "KeyAttrs",
2307 "Nd",
2308 self.orig_loc,
2309 self.buf.as_ptr() as usize,
2310 ))
2311 }
2312 pub fn get_skb_mark(&self) -> Result<u32, ErrorContext> {
2313 let mut iter = self.clone();
2314 iter.pos = 0;
2315 for attr in iter {
2316 if let KeyAttrs::SkbMark(val) = attr? {
2317 return Ok(val);
2318 }
2319 }
2320 Err(ErrorContext::new_missing(
2321 "KeyAttrs",
2322 "SkbMark",
2323 self.orig_loc,
2324 self.buf.as_ptr() as usize,
2325 ))
2326 }
2327 pub fn get_tunnel(&self) -> Result<IterableTunnelKeyAttrs<'a>, ErrorContext> {
2328 let mut iter = self.clone();
2329 iter.pos = 0;
2330 for attr in iter {
2331 if let KeyAttrs::Tunnel(val) = attr? {
2332 return Ok(val);
2333 }
2334 }
2335 Err(ErrorContext::new_missing(
2336 "KeyAttrs",
2337 "Tunnel",
2338 self.orig_loc,
2339 self.buf.as_ptr() as usize,
2340 ))
2341 }
2342 pub fn get_sctp(&self) -> Result<OvsKeySctp, ErrorContext> {
2343 let mut iter = self.clone();
2344 iter.pos = 0;
2345 for attr in iter {
2346 if let KeyAttrs::Sctp(val) = attr? {
2347 return Ok(val);
2348 }
2349 }
2350 Err(ErrorContext::new_missing(
2351 "KeyAttrs",
2352 "Sctp",
2353 self.orig_loc,
2354 self.buf.as_ptr() as usize,
2355 ))
2356 }
2357 pub fn get_tcp_flags(&self) -> Result<u16, ErrorContext> {
2358 let mut iter = self.clone();
2359 iter.pos = 0;
2360 for attr in iter {
2361 if let KeyAttrs::TcpFlags(val) = attr? {
2362 return Ok(val);
2363 }
2364 }
2365 Err(ErrorContext::new_missing(
2366 "KeyAttrs",
2367 "TcpFlags",
2368 self.orig_loc,
2369 self.buf.as_ptr() as usize,
2370 ))
2371 }
2372 #[doc = "Value 0 indicates the hash is not computed by the datapath\\."]
2373 pub fn get_dp_hash(&self) -> Result<u32, ErrorContext> {
2374 let mut iter = self.clone();
2375 iter.pos = 0;
2376 for attr in iter {
2377 if let KeyAttrs::DpHash(val) = attr? {
2378 return Ok(val);
2379 }
2380 }
2381 Err(ErrorContext::new_missing(
2382 "KeyAttrs",
2383 "DpHash",
2384 self.orig_loc,
2385 self.buf.as_ptr() as usize,
2386 ))
2387 }
2388 pub fn get_recirc_id(&self) -> Result<u32, ErrorContext> {
2389 let mut iter = self.clone();
2390 iter.pos = 0;
2391 for attr in iter {
2392 if let KeyAttrs::RecircId(val) = attr? {
2393 return Ok(val);
2394 }
2395 }
2396 Err(ErrorContext::new_missing(
2397 "KeyAttrs",
2398 "RecircId",
2399 self.orig_loc,
2400 self.buf.as_ptr() as usize,
2401 ))
2402 }
2403 pub fn get_mpls(&self) -> Result<OvsKeyMpls, ErrorContext> {
2404 let mut iter = self.clone();
2405 iter.pos = 0;
2406 for attr in iter {
2407 if let KeyAttrs::Mpls(val) = attr? {
2408 return Ok(val);
2409 }
2410 }
2411 Err(ErrorContext::new_missing(
2412 "KeyAttrs",
2413 "Mpls",
2414 self.orig_loc,
2415 self.buf.as_ptr() as usize,
2416 ))
2417 }
2418 #[doc = "Associated type: [`CtStateFlags`] (1 bit per enumeration)"]
2419 pub fn get_ct_state(&self) -> Result<u32, ErrorContext> {
2420 let mut iter = self.clone();
2421 iter.pos = 0;
2422 for attr in iter {
2423 if let KeyAttrs::CtState(val) = attr? {
2424 return Ok(val);
2425 }
2426 }
2427 Err(ErrorContext::new_missing(
2428 "KeyAttrs",
2429 "CtState",
2430 self.orig_loc,
2431 self.buf.as_ptr() as usize,
2432 ))
2433 }
2434 #[doc = "connection tracking zone"]
2435 pub fn get_ct_zone(&self) -> Result<u16, ErrorContext> {
2436 let mut iter = self.clone();
2437 iter.pos = 0;
2438 for attr in iter {
2439 if let KeyAttrs::CtZone(val) = attr? {
2440 return Ok(val);
2441 }
2442 }
2443 Err(ErrorContext::new_missing(
2444 "KeyAttrs",
2445 "CtZone",
2446 self.orig_loc,
2447 self.buf.as_ptr() as usize,
2448 ))
2449 }
2450 #[doc = "connection tracking mark"]
2451 pub fn get_ct_mark(&self) -> Result<u32, ErrorContext> {
2452 let mut iter = self.clone();
2453 iter.pos = 0;
2454 for attr in iter {
2455 if let KeyAttrs::CtMark(val) = attr? {
2456 return Ok(val);
2457 }
2458 }
2459 Err(ErrorContext::new_missing(
2460 "KeyAttrs",
2461 "CtMark",
2462 self.orig_loc,
2463 self.buf.as_ptr() as usize,
2464 ))
2465 }
2466 #[doc = "16\\-octet connection tracking label"]
2467 pub fn get_ct_labels(&self) -> Result<&'a [u8], ErrorContext> {
2468 let mut iter = self.clone();
2469 iter.pos = 0;
2470 for attr in iter {
2471 if let KeyAttrs::CtLabels(val) = attr? {
2472 return Ok(val);
2473 }
2474 }
2475 Err(ErrorContext::new_missing(
2476 "KeyAttrs",
2477 "CtLabels",
2478 self.orig_loc,
2479 self.buf.as_ptr() as usize,
2480 ))
2481 }
2482 pub fn get_ct_orig_tuple_ipv4(&self) -> Result<OvsKeyCtTupleIpv4, ErrorContext> {
2483 let mut iter = self.clone();
2484 iter.pos = 0;
2485 for attr in iter {
2486 if let KeyAttrs::CtOrigTupleIpv4(val) = attr? {
2487 return Ok(val);
2488 }
2489 }
2490 Err(ErrorContext::new_missing(
2491 "KeyAttrs",
2492 "CtOrigTupleIpv4",
2493 self.orig_loc,
2494 self.buf.as_ptr() as usize,
2495 ))
2496 }
2497 #[doc = "struct ovs\\_key\\_ct\\_tuple\\_ipv6"]
2498 pub fn get_ct_orig_tuple_ipv6(&self) -> Result<&'a [u8], ErrorContext> {
2499 let mut iter = self.clone();
2500 iter.pos = 0;
2501 for attr in iter {
2502 if let KeyAttrs::CtOrigTupleIpv6(val) = attr? {
2503 return Ok(val);
2504 }
2505 }
2506 Err(ErrorContext::new_missing(
2507 "KeyAttrs",
2508 "CtOrigTupleIpv6",
2509 self.orig_loc,
2510 self.buf.as_ptr() as usize,
2511 ))
2512 }
2513 pub fn get_nsh(&self) -> Result<IterableOvsNshKeyAttrs<'a>, ErrorContext> {
2514 let mut iter = self.clone();
2515 iter.pos = 0;
2516 for attr in iter {
2517 if let KeyAttrs::Nsh(val) = attr? {
2518 return Ok(val);
2519 }
2520 }
2521 Err(ErrorContext::new_missing(
2522 "KeyAttrs",
2523 "Nsh",
2524 self.orig_loc,
2525 self.buf.as_ptr() as usize,
2526 ))
2527 }
2528 #[doc = "Should not be sent to the kernel"]
2529 pub fn get_packet_type(&self) -> Result<u32, ErrorContext> {
2530 let mut iter = self.clone();
2531 iter.pos = 0;
2532 for attr in iter {
2533 if let KeyAttrs::PacketType(val) = attr? {
2534 return Ok(val);
2535 }
2536 }
2537 Err(ErrorContext::new_missing(
2538 "KeyAttrs",
2539 "PacketType",
2540 self.orig_loc,
2541 self.buf.as_ptr() as usize,
2542 ))
2543 }
2544 #[doc = "Should not be sent to the kernel"]
2545 pub fn get_nd_extensions(&self) -> Result<&'a [u8], ErrorContext> {
2546 let mut iter = self.clone();
2547 iter.pos = 0;
2548 for attr in iter {
2549 if let KeyAttrs::NdExtensions(val) = attr? {
2550 return Ok(val);
2551 }
2552 }
2553 Err(ErrorContext::new_missing(
2554 "KeyAttrs",
2555 "NdExtensions",
2556 self.orig_loc,
2557 self.buf.as_ptr() as usize,
2558 ))
2559 }
2560 #[doc = "struct ip\\_tunnel\\_info"]
2561 pub fn get_tunnel_info(&self) -> Result<&'a [u8], ErrorContext> {
2562 let mut iter = self.clone();
2563 iter.pos = 0;
2564 for attr in iter {
2565 if let KeyAttrs::TunnelInfo(val) = attr? {
2566 return Ok(val);
2567 }
2568 }
2569 Err(ErrorContext::new_missing(
2570 "KeyAttrs",
2571 "TunnelInfo",
2572 self.orig_loc,
2573 self.buf.as_ptr() as usize,
2574 ))
2575 }
2576 #[doc = "struct ovs\\_key\\_ipv6\\_exthdr"]
2577 pub fn get_ipv6_exthdrs(&self) -> Result<OvsKeyIpv6Exthdrs, ErrorContext> {
2578 let mut iter = self.clone();
2579 iter.pos = 0;
2580 for attr in iter {
2581 if let KeyAttrs::Ipv6Exthdrs(val) = attr? {
2582 return Ok(val);
2583 }
2584 }
2585 Err(ErrorContext::new_missing(
2586 "KeyAttrs",
2587 "Ipv6Exthdrs",
2588 self.orig_loc,
2589 self.buf.as_ptr() as usize,
2590 ))
2591 }
2592}
2593impl KeyAttrs<'_> {
2594 pub fn new<'a>(buf: &'a [u8]) -> IterableKeyAttrs<'a> {
2595 IterableKeyAttrs::with_loc(buf, buf.as_ptr() as usize)
2596 }
2597 fn attr_from_type(r#type: u16) -> Option<&'static str> {
2598 let res = match r#type {
2599 1u16 => "Encap",
2600 2u16 => "Priority",
2601 3u16 => "InPort",
2602 4u16 => "Ethernet",
2603 5u16 => "Vlan",
2604 6u16 => "Ethertype",
2605 7u16 => "Ipv4",
2606 8u16 => "Ipv6",
2607 9u16 => "Tcp",
2608 10u16 => "Udp",
2609 11u16 => "Icmp",
2610 12u16 => "Icmpv6",
2611 13u16 => "Arp",
2612 14u16 => "Nd",
2613 15u16 => "SkbMark",
2614 16u16 => "Tunnel",
2615 17u16 => "Sctp",
2616 18u16 => "TcpFlags",
2617 19u16 => "DpHash",
2618 20u16 => "RecircId",
2619 21u16 => "Mpls",
2620 22u16 => "CtState",
2621 23u16 => "CtZone",
2622 24u16 => "CtMark",
2623 25u16 => "CtLabels",
2624 26u16 => "CtOrigTupleIpv4",
2625 27u16 => "CtOrigTupleIpv6",
2626 28u16 => "Nsh",
2627 29u16 => "PacketType",
2628 30u16 => "NdExtensions",
2629 31u16 => "TunnelInfo",
2630 32u16 => "Ipv6Exthdrs",
2631 _ => return None,
2632 };
2633 Some(res)
2634 }
2635}
2636#[derive(Clone, Copy, Default)]
2637pub struct IterableKeyAttrs<'a> {
2638 buf: &'a [u8],
2639 pos: usize,
2640 orig_loc: usize,
2641}
2642impl<'a> IterableKeyAttrs<'a> {
2643 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
2644 Self {
2645 buf,
2646 pos: 0,
2647 orig_loc,
2648 }
2649 }
2650 pub fn get_buf(&self) -> &'a [u8] {
2651 self.buf
2652 }
2653}
2654impl<'a> Iterator for IterableKeyAttrs<'a> {
2655 type Item = Result<KeyAttrs<'a>, ErrorContext>;
2656 fn next(&mut self) -> Option<Self::Item> {
2657 let pos = self.pos;
2658 let mut r#type;
2659 loop {
2660 r#type = None;
2661 if self.buf.len() == self.pos {
2662 return None;
2663 }
2664 let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
2665 break;
2666 };
2667 r#type = Some(header.r#type);
2668 let res = match header.r#type {
2669 1u16 => KeyAttrs::Encap({
2670 let res = Some(IterableKeyAttrs::with_loc(next, self.orig_loc));
2671 let Some(val) = res else { break };
2672 val
2673 }),
2674 2u16 => KeyAttrs::Priority({
2675 let res = parse_u32(next);
2676 let Some(val) = res else { break };
2677 val
2678 }),
2679 3u16 => KeyAttrs::InPort({
2680 let res = parse_u32(next);
2681 let Some(val) = res else { break };
2682 val
2683 }),
2684 4u16 => KeyAttrs::Ethernet({
2685 let res = Some(OvsKeyEthernet::new_from_zeroed(next));
2686 let Some(val) = res else { break };
2687 val
2688 }),
2689 5u16 => KeyAttrs::Vlan({
2690 let res = parse_be_u16(next);
2691 let Some(val) = res else { break };
2692 val
2693 }),
2694 6u16 => KeyAttrs::Ethertype({
2695 let res = parse_be_u16(next);
2696 let Some(val) = res else { break };
2697 val
2698 }),
2699 7u16 => KeyAttrs::Ipv4({
2700 let res = Some(OvsKeyIpv4::new_from_zeroed(next));
2701 let Some(val) = res else { break };
2702 val
2703 }),
2704 8u16 => KeyAttrs::Ipv6({
2705 let res = Some(OvsKeyIpv6::new_from_zeroed(next));
2706 let Some(val) = res else { break };
2707 val
2708 }),
2709 9u16 => KeyAttrs::Tcp({
2710 let res = Some(OvsKeyTcp::new_from_zeroed(next));
2711 let Some(val) = res else { break };
2712 val
2713 }),
2714 10u16 => KeyAttrs::Udp({
2715 let res = Some(OvsKeyUdp::new_from_zeroed(next));
2716 let Some(val) = res else { break };
2717 val
2718 }),
2719 11u16 => KeyAttrs::Icmp({
2720 let res = Some(OvsKeyIcmp::new_from_zeroed(next));
2721 let Some(val) = res else { break };
2722 val
2723 }),
2724 12u16 => KeyAttrs::Icmpv6({
2725 let res = Some(OvsKeyIcmp::new_from_zeroed(next));
2726 let Some(val) = res else { break };
2727 val
2728 }),
2729 13u16 => KeyAttrs::Arp({
2730 let res = Some(OvsKeyArp::new_from_zeroed(next));
2731 let Some(val) = res else { break };
2732 val
2733 }),
2734 14u16 => KeyAttrs::Nd({
2735 let res = Some(OvsKeyNd::new_from_zeroed(next));
2736 let Some(val) = res else { break };
2737 val
2738 }),
2739 15u16 => KeyAttrs::SkbMark({
2740 let res = parse_u32(next);
2741 let Some(val) = res else { break };
2742 val
2743 }),
2744 16u16 => KeyAttrs::Tunnel({
2745 let res = Some(IterableTunnelKeyAttrs::with_loc(next, self.orig_loc));
2746 let Some(val) = res else { break };
2747 val
2748 }),
2749 17u16 => KeyAttrs::Sctp({
2750 let res = Some(OvsKeySctp::new_from_zeroed(next));
2751 let Some(val) = res else { break };
2752 val
2753 }),
2754 18u16 => KeyAttrs::TcpFlags({
2755 let res = parse_be_u16(next);
2756 let Some(val) = res else { break };
2757 val
2758 }),
2759 19u16 => KeyAttrs::DpHash({
2760 let res = parse_u32(next);
2761 let Some(val) = res else { break };
2762 val
2763 }),
2764 20u16 => KeyAttrs::RecircId({
2765 let res = parse_u32(next);
2766 let Some(val) = res else { break };
2767 val
2768 }),
2769 21u16 => KeyAttrs::Mpls({
2770 let res = Some(OvsKeyMpls::new_from_zeroed(next));
2771 let Some(val) = res else { break };
2772 val
2773 }),
2774 22u16 => KeyAttrs::CtState({
2775 let res = parse_u32(next);
2776 let Some(val) = res else { break };
2777 val
2778 }),
2779 23u16 => KeyAttrs::CtZone({
2780 let res = parse_u16(next);
2781 let Some(val) = res else { break };
2782 val
2783 }),
2784 24u16 => KeyAttrs::CtMark({
2785 let res = parse_u32(next);
2786 let Some(val) = res else { break };
2787 val
2788 }),
2789 25u16 => KeyAttrs::CtLabels({
2790 let res = Some(next);
2791 let Some(val) = res else { break };
2792 val
2793 }),
2794 26u16 => KeyAttrs::CtOrigTupleIpv4({
2795 let res = Some(OvsKeyCtTupleIpv4::new_from_zeroed(next));
2796 let Some(val) = res else { break };
2797 val
2798 }),
2799 27u16 => KeyAttrs::CtOrigTupleIpv6({
2800 let res = Some(next);
2801 let Some(val) = res else { break };
2802 val
2803 }),
2804 28u16 => KeyAttrs::Nsh({
2805 let res = Some(IterableOvsNshKeyAttrs::with_loc(next, self.orig_loc));
2806 let Some(val) = res else { break };
2807 val
2808 }),
2809 29u16 => KeyAttrs::PacketType({
2810 let res = parse_be_u32(next);
2811 let Some(val) = res else { break };
2812 val
2813 }),
2814 30u16 => KeyAttrs::NdExtensions({
2815 let res = Some(next);
2816 let Some(val) = res else { break };
2817 val
2818 }),
2819 31u16 => KeyAttrs::TunnelInfo({
2820 let res = Some(next);
2821 let Some(val) = res else { break };
2822 val
2823 }),
2824 32u16 => KeyAttrs::Ipv6Exthdrs({
2825 let res = Some(OvsKeyIpv6Exthdrs::new_from_zeroed(next));
2826 let Some(val) = res else { break };
2827 val
2828 }),
2829 n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
2830 n => continue,
2831 };
2832 return Some(Ok(res));
2833 }
2834 Some(Err(ErrorContext::new(
2835 "KeyAttrs",
2836 r#type.and_then(|t| KeyAttrs::attr_from_type(t)),
2837 self.orig_loc,
2838 self.buf.as_ptr().wrapping_add(pos) as usize,
2839 )))
2840 }
2841}
2842impl<'a> std::fmt::Debug for IterableKeyAttrs<'_> {
2843 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2844 let mut fmt = f.debug_struct("KeyAttrs");
2845 for attr in self.clone() {
2846 let attr = match attr {
2847 Ok(a) => a,
2848 Err(err) => {
2849 fmt.finish()?;
2850 f.write_str("Err(")?;
2851 err.fmt(f)?;
2852 return f.write_str(")");
2853 }
2854 };
2855 match attr {
2856 KeyAttrs::Encap(val) => fmt.field("Encap", &val),
2857 KeyAttrs::Priority(val) => fmt.field("Priority", &val),
2858 KeyAttrs::InPort(val) => fmt.field("InPort", &val),
2859 KeyAttrs::Ethernet(val) => fmt.field("Ethernet", &val),
2860 KeyAttrs::Vlan(val) => fmt.field("Vlan", &val),
2861 KeyAttrs::Ethertype(val) => fmt.field("Ethertype", &val),
2862 KeyAttrs::Ipv4(val) => fmt.field("Ipv4", &val),
2863 KeyAttrs::Ipv6(val) => fmt.field("Ipv6", &val),
2864 KeyAttrs::Tcp(val) => fmt.field("Tcp", &val),
2865 KeyAttrs::Udp(val) => fmt.field("Udp", &val),
2866 KeyAttrs::Icmp(val) => fmt.field("Icmp", &val),
2867 KeyAttrs::Icmpv6(val) => fmt.field("Icmpv6", &val),
2868 KeyAttrs::Arp(val) => fmt.field("Arp", &val),
2869 KeyAttrs::Nd(val) => fmt.field("Nd", &val),
2870 KeyAttrs::SkbMark(val) => fmt.field("SkbMark", &val),
2871 KeyAttrs::Tunnel(val) => fmt.field("Tunnel", &val),
2872 KeyAttrs::Sctp(val) => fmt.field("Sctp", &val),
2873 KeyAttrs::TcpFlags(val) => fmt.field("TcpFlags", &val),
2874 KeyAttrs::DpHash(val) => fmt.field("DpHash", &val),
2875 KeyAttrs::RecircId(val) => fmt.field("RecircId", &val),
2876 KeyAttrs::Mpls(val) => fmt.field("Mpls", &val),
2877 KeyAttrs::CtState(val) => fmt.field(
2878 "CtState",
2879 &FormatFlags(val.into(), CtStateFlags::from_value),
2880 ),
2881 KeyAttrs::CtZone(val) => fmt.field("CtZone", &val),
2882 KeyAttrs::CtMark(val) => fmt.field("CtMark", &val),
2883 KeyAttrs::CtLabels(val) => fmt.field("CtLabels", &FormatHex(val)),
2884 KeyAttrs::CtOrigTupleIpv4(val) => fmt.field("CtOrigTupleIpv4", &val),
2885 KeyAttrs::CtOrigTupleIpv6(val) => fmt.field("CtOrigTupleIpv6", &val),
2886 KeyAttrs::Nsh(val) => fmt.field("Nsh", &val),
2887 KeyAttrs::PacketType(val) => fmt.field("PacketType", &val),
2888 KeyAttrs::NdExtensions(val) => fmt.field("NdExtensions", &val),
2889 KeyAttrs::TunnelInfo(val) => fmt.field("TunnelInfo", &val),
2890 KeyAttrs::Ipv6Exthdrs(val) => fmt.field("Ipv6Exthdrs", &val),
2891 };
2892 }
2893 fmt.finish()
2894 }
2895}
2896impl IterableKeyAttrs<'_> {
2897 pub fn lookup_attr(
2898 &self,
2899 offset: usize,
2900 missing_type: Option<u16>,
2901 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
2902 let mut stack = Vec::new();
2903 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
2904 if missing_type.is_some() && cur == offset {
2905 stack.push(("KeyAttrs", offset));
2906 return (
2907 stack,
2908 missing_type.and_then(|t| KeyAttrs::attr_from_type(t)),
2909 );
2910 }
2911 if cur > offset || cur + self.buf.len() < offset {
2912 return (stack, None);
2913 }
2914 let mut attrs = self.clone();
2915 let mut last_off = cur + attrs.pos;
2916 let mut missing = None;
2917 while let Some(attr) = attrs.next() {
2918 let Ok(attr) = attr else { break };
2919 match attr {
2920 KeyAttrs::Encap(val) => {
2921 (stack, missing) = val.lookup_attr(offset, missing_type);
2922 if !stack.is_empty() {
2923 break;
2924 }
2925 }
2926 KeyAttrs::Priority(val) => {
2927 if last_off == offset {
2928 stack.push(("Priority", last_off));
2929 break;
2930 }
2931 }
2932 KeyAttrs::InPort(val) => {
2933 if last_off == offset {
2934 stack.push(("InPort", last_off));
2935 break;
2936 }
2937 }
2938 KeyAttrs::Ethernet(val) => {
2939 if last_off == offset {
2940 stack.push(("Ethernet", last_off));
2941 break;
2942 }
2943 }
2944 KeyAttrs::Vlan(val) => {
2945 if last_off == offset {
2946 stack.push(("Vlan", last_off));
2947 break;
2948 }
2949 }
2950 KeyAttrs::Ethertype(val) => {
2951 if last_off == offset {
2952 stack.push(("Ethertype", last_off));
2953 break;
2954 }
2955 }
2956 KeyAttrs::Ipv4(val) => {
2957 if last_off == offset {
2958 stack.push(("Ipv4", last_off));
2959 break;
2960 }
2961 }
2962 KeyAttrs::Ipv6(val) => {
2963 if last_off == offset {
2964 stack.push(("Ipv6", last_off));
2965 break;
2966 }
2967 }
2968 KeyAttrs::Tcp(val) => {
2969 if last_off == offset {
2970 stack.push(("Tcp", last_off));
2971 break;
2972 }
2973 }
2974 KeyAttrs::Udp(val) => {
2975 if last_off == offset {
2976 stack.push(("Udp", last_off));
2977 break;
2978 }
2979 }
2980 KeyAttrs::Icmp(val) => {
2981 if last_off == offset {
2982 stack.push(("Icmp", last_off));
2983 break;
2984 }
2985 }
2986 KeyAttrs::Icmpv6(val) => {
2987 if last_off == offset {
2988 stack.push(("Icmpv6", last_off));
2989 break;
2990 }
2991 }
2992 KeyAttrs::Arp(val) => {
2993 if last_off == offset {
2994 stack.push(("Arp", last_off));
2995 break;
2996 }
2997 }
2998 KeyAttrs::Nd(val) => {
2999 if last_off == offset {
3000 stack.push(("Nd", last_off));
3001 break;
3002 }
3003 }
3004 KeyAttrs::SkbMark(val) => {
3005 if last_off == offset {
3006 stack.push(("SkbMark", last_off));
3007 break;
3008 }
3009 }
3010 KeyAttrs::Tunnel(val) => {
3011 (stack, missing) = val.lookup_attr(offset, missing_type);
3012 if !stack.is_empty() {
3013 break;
3014 }
3015 }
3016 KeyAttrs::Sctp(val) => {
3017 if last_off == offset {
3018 stack.push(("Sctp", last_off));
3019 break;
3020 }
3021 }
3022 KeyAttrs::TcpFlags(val) => {
3023 if last_off == offset {
3024 stack.push(("TcpFlags", last_off));
3025 break;
3026 }
3027 }
3028 KeyAttrs::DpHash(val) => {
3029 if last_off == offset {
3030 stack.push(("DpHash", last_off));
3031 break;
3032 }
3033 }
3034 KeyAttrs::RecircId(val) => {
3035 if last_off == offset {
3036 stack.push(("RecircId", last_off));
3037 break;
3038 }
3039 }
3040 KeyAttrs::Mpls(val) => {
3041 if last_off == offset {
3042 stack.push(("Mpls", last_off));
3043 break;
3044 }
3045 }
3046 KeyAttrs::CtState(val) => {
3047 if last_off == offset {
3048 stack.push(("CtState", last_off));
3049 break;
3050 }
3051 }
3052 KeyAttrs::CtZone(val) => {
3053 if last_off == offset {
3054 stack.push(("CtZone", last_off));
3055 break;
3056 }
3057 }
3058 KeyAttrs::CtMark(val) => {
3059 if last_off == offset {
3060 stack.push(("CtMark", last_off));
3061 break;
3062 }
3063 }
3064 KeyAttrs::CtLabels(val) => {
3065 if last_off == offset {
3066 stack.push(("CtLabels", last_off));
3067 break;
3068 }
3069 }
3070 KeyAttrs::CtOrigTupleIpv4(val) => {
3071 if last_off == offset {
3072 stack.push(("CtOrigTupleIpv4", last_off));
3073 break;
3074 }
3075 }
3076 KeyAttrs::CtOrigTupleIpv6(val) => {
3077 if last_off == offset {
3078 stack.push(("CtOrigTupleIpv6", last_off));
3079 break;
3080 }
3081 }
3082 KeyAttrs::Nsh(val) => {
3083 (stack, missing) = val.lookup_attr(offset, missing_type);
3084 if !stack.is_empty() {
3085 break;
3086 }
3087 }
3088 KeyAttrs::PacketType(val) => {
3089 if last_off == offset {
3090 stack.push(("PacketType", last_off));
3091 break;
3092 }
3093 }
3094 KeyAttrs::NdExtensions(val) => {
3095 if last_off == offset {
3096 stack.push(("NdExtensions", last_off));
3097 break;
3098 }
3099 }
3100 KeyAttrs::TunnelInfo(val) => {
3101 if last_off == offset {
3102 stack.push(("TunnelInfo", last_off));
3103 break;
3104 }
3105 }
3106 KeyAttrs::Ipv6Exthdrs(val) => {
3107 if last_off == offset {
3108 stack.push(("Ipv6Exthdrs", last_off));
3109 break;
3110 }
3111 }
3112 _ => {}
3113 };
3114 last_off = cur + attrs.pos;
3115 }
3116 if !stack.is_empty() {
3117 stack.push(("KeyAttrs", cur));
3118 }
3119 (stack, missing)
3120 }
3121}
3122#[derive(Clone)]
3123pub enum ActionAttrs<'a> {
3124 #[doc = "ovs port number in datapath"]
3125 Output(u32),
3126 Userspace(IterableUserspaceAttrs<'a>),
3127 #[doc = "Replaces the contents of an existing header\\. The single nested\nattribute specifies a header to modify and its value\\.\n"]
3128 Set(IterableKeyAttrs<'a>),
3129 #[doc = "Push a new outermost 802\\.1Q or 802\\.1ad header onto the packet\\."]
3130 PushVlan(OvsActionPushVlan),
3131 #[doc = "Pop the outermost 802\\.1Q or 802\\.1ad header from the packet\\."]
3132 PopVlan(()),
3133 #[doc = "Probabilistically executes actions, as specified in the nested\nattributes\\.\n"]
3134 Sample(IterableSampleAttrs<'a>),
3135 #[doc = "recirc id"]
3136 Recirc(u32),
3137 Hash(OvsActionHash),
3138 #[doc = "Push a new MPLS label stack entry onto the top of the packets MPLS\nlabel stack\\. 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"]
3139 PushMpls(OvsActionPushMpls),
3140 #[doc = "ethertype"]
3141 PopMpls(u16),
3142 #[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\nthe packet header field, rest of the bits are left unchanged\\. The\nnon\\-masked value bits must be passed in as zeroes\\. Masking is not\nsupported for the OVS\\_KEY\\_ATTR\\_TUNNEL attribute\\.\n"]
3143 SetMasked(IterableKeyAttrs<'a>),
3144 #[doc = "Track the connection\\. Populate the conntrack\\-related entries\nin the flow key\\.\n"]
3145 Ct(IterableCtAttrs<'a>),
3146 #[doc = "struct ovs\\_action\\_trunc is a u32 max length"]
3147 Trunc(u32),
3148 #[doc = "struct ovs\\_action\\_push\\_eth"]
3149 PushEth(&'a [u8]),
3150 PopEth(()),
3151 CtClear(()),
3152 #[doc = "Push NSH header to the packet\\.\n"]
3153 PushNsh(IterableOvsNshKeyAttrs<'a>),
3154 #[doc = "Pop the outermost NSH header off the packet\\.\n"]
3155 PopNsh(()),
3156 #[doc = "Run packet through a meter, which may drop the packet, or modify the\npacket (e\\.g\\., change the DSCP field)\n"]
3157 Meter(u32),
3158 #[doc = "Make a copy of the packet and execute a list of actions without\naffecting the original packet and key\\.\n"]
3159 Clone(IterableActionAttrs<'a>),
3160 #[doc = "Check the packet length and execute a set of actions if greater than\nthe specified packet length, else execute another set of actions\\.\n"]
3161 CheckPktLen(IterableCheckPktLenAttrs<'a>),
3162 #[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"]
3163 AddMpls(OvsActionAddMpls),
3164 DecTtl(IterableDecTtlAttrs<'a>),
3165 #[doc = "Sends a packet sample to psample for external observation\\.\n"]
3166 Psample(IterablePsampleAttrs<'a>),
3167}
3168impl<'a> IterableActionAttrs<'a> {
3169 #[doc = "ovs port number in datapath"]
3170 pub fn get_output(&self) -> Result<u32, ErrorContext> {
3171 let mut iter = self.clone();
3172 iter.pos = 0;
3173 for attr in iter {
3174 if let ActionAttrs::Output(val) = attr? {
3175 return Ok(val);
3176 }
3177 }
3178 Err(ErrorContext::new_missing(
3179 "ActionAttrs",
3180 "Output",
3181 self.orig_loc,
3182 self.buf.as_ptr() as usize,
3183 ))
3184 }
3185 pub fn get_userspace(&self) -> Result<IterableUserspaceAttrs<'a>, ErrorContext> {
3186 let mut iter = self.clone();
3187 iter.pos = 0;
3188 for attr in iter {
3189 if let ActionAttrs::Userspace(val) = attr? {
3190 return Ok(val);
3191 }
3192 }
3193 Err(ErrorContext::new_missing(
3194 "ActionAttrs",
3195 "Userspace",
3196 self.orig_loc,
3197 self.buf.as_ptr() as usize,
3198 ))
3199 }
3200 #[doc = "Replaces the contents of an existing header\\. The single nested\nattribute specifies a header to modify and its value\\.\n"]
3201 pub fn get_set(&self) -> Result<IterableKeyAttrs<'a>, ErrorContext> {
3202 let mut iter = self.clone();
3203 iter.pos = 0;
3204 for attr in iter {
3205 if let ActionAttrs::Set(val) = attr? {
3206 return Ok(val);
3207 }
3208 }
3209 Err(ErrorContext::new_missing(
3210 "ActionAttrs",
3211 "Set",
3212 self.orig_loc,
3213 self.buf.as_ptr() as usize,
3214 ))
3215 }
3216 #[doc = "Push a new outermost 802\\.1Q or 802\\.1ad header onto the packet\\."]
3217 pub fn get_push_vlan(&self) -> Result<OvsActionPushVlan, ErrorContext> {
3218 let mut iter = self.clone();
3219 iter.pos = 0;
3220 for attr in iter {
3221 if let ActionAttrs::PushVlan(val) = attr? {
3222 return Ok(val);
3223 }
3224 }
3225 Err(ErrorContext::new_missing(
3226 "ActionAttrs",
3227 "PushVlan",
3228 self.orig_loc,
3229 self.buf.as_ptr() as usize,
3230 ))
3231 }
3232 #[doc = "Pop the outermost 802\\.1Q or 802\\.1ad header from the packet\\."]
3233 pub fn get_pop_vlan(&self) -> Result<(), ErrorContext> {
3234 let mut iter = self.clone();
3235 iter.pos = 0;
3236 for attr in iter {
3237 if let ActionAttrs::PopVlan(val) = attr? {
3238 return Ok(val);
3239 }
3240 }
3241 Err(ErrorContext::new_missing(
3242 "ActionAttrs",
3243 "PopVlan",
3244 self.orig_loc,
3245 self.buf.as_ptr() as usize,
3246 ))
3247 }
3248 #[doc = "Probabilistically executes actions, as specified in the nested\nattributes\\.\n"]
3249 pub fn get_sample(&self) -> Result<IterableSampleAttrs<'a>, ErrorContext> {
3250 let mut iter = self.clone();
3251 iter.pos = 0;
3252 for attr in iter {
3253 if let ActionAttrs::Sample(val) = attr? {
3254 return Ok(val);
3255 }
3256 }
3257 Err(ErrorContext::new_missing(
3258 "ActionAttrs",
3259 "Sample",
3260 self.orig_loc,
3261 self.buf.as_ptr() as usize,
3262 ))
3263 }
3264 #[doc = "recirc id"]
3265 pub fn get_recirc(&self) -> Result<u32, ErrorContext> {
3266 let mut iter = self.clone();
3267 iter.pos = 0;
3268 for attr in iter {
3269 if let ActionAttrs::Recirc(val) = attr? {
3270 return Ok(val);
3271 }
3272 }
3273 Err(ErrorContext::new_missing(
3274 "ActionAttrs",
3275 "Recirc",
3276 self.orig_loc,
3277 self.buf.as_ptr() as usize,
3278 ))
3279 }
3280 pub fn get_hash(&self) -> Result<OvsActionHash, ErrorContext> {
3281 let mut iter = self.clone();
3282 iter.pos = 0;
3283 for attr in iter {
3284 if let ActionAttrs::Hash(val) = attr? {
3285 return Ok(val);
3286 }
3287 }
3288 Err(ErrorContext::new_missing(
3289 "ActionAttrs",
3290 "Hash",
3291 self.orig_loc,
3292 self.buf.as_ptr() as usize,
3293 ))
3294 }
3295 #[doc = "Push a new MPLS label stack entry onto the top of the packets MPLS\nlabel stack\\. 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"]
3296 pub fn get_push_mpls(&self) -> Result<OvsActionPushMpls, ErrorContext> {
3297 let mut iter = self.clone();
3298 iter.pos = 0;
3299 for attr in iter {
3300 if let ActionAttrs::PushMpls(val) = attr? {
3301 return Ok(val);
3302 }
3303 }
3304 Err(ErrorContext::new_missing(
3305 "ActionAttrs",
3306 "PushMpls",
3307 self.orig_loc,
3308 self.buf.as_ptr() as usize,
3309 ))
3310 }
3311 #[doc = "ethertype"]
3312 pub fn get_pop_mpls(&self) -> Result<u16, ErrorContext> {
3313 let mut iter = self.clone();
3314 iter.pos = 0;
3315 for attr in iter {
3316 if let ActionAttrs::PopMpls(val) = attr? {
3317 return Ok(val);
3318 }
3319 }
3320 Err(ErrorContext::new_missing(
3321 "ActionAttrs",
3322 "PopMpls",
3323 self.orig_loc,
3324 self.buf.as_ptr() as usize,
3325 ))
3326 }
3327 #[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\nthe packet header field, rest of the bits are left unchanged\\. The\nnon\\-masked value bits must be passed in as zeroes\\. Masking is not\nsupported for the OVS\\_KEY\\_ATTR\\_TUNNEL attribute\\.\n"]
3328 pub fn get_set_masked(&self) -> Result<IterableKeyAttrs<'a>, ErrorContext> {
3329 let mut iter = self.clone();
3330 iter.pos = 0;
3331 for attr in iter {
3332 if let ActionAttrs::SetMasked(val) = attr? {
3333 return Ok(val);
3334 }
3335 }
3336 Err(ErrorContext::new_missing(
3337 "ActionAttrs",
3338 "SetMasked",
3339 self.orig_loc,
3340 self.buf.as_ptr() as usize,
3341 ))
3342 }
3343 #[doc = "Track the connection\\. Populate the conntrack\\-related entries\nin the flow key\\.\n"]
3344 pub fn get_ct(&self) -> Result<IterableCtAttrs<'a>, ErrorContext> {
3345 let mut iter = self.clone();
3346 iter.pos = 0;
3347 for attr in iter {
3348 if let ActionAttrs::Ct(val) = attr? {
3349 return Ok(val);
3350 }
3351 }
3352 Err(ErrorContext::new_missing(
3353 "ActionAttrs",
3354 "Ct",
3355 self.orig_loc,
3356 self.buf.as_ptr() as usize,
3357 ))
3358 }
3359 #[doc = "struct ovs\\_action\\_trunc is a u32 max length"]
3360 pub fn get_trunc(&self) -> Result<u32, ErrorContext> {
3361 let mut iter = self.clone();
3362 iter.pos = 0;
3363 for attr in iter {
3364 if let ActionAttrs::Trunc(val) = attr? {
3365 return Ok(val);
3366 }
3367 }
3368 Err(ErrorContext::new_missing(
3369 "ActionAttrs",
3370 "Trunc",
3371 self.orig_loc,
3372 self.buf.as_ptr() as usize,
3373 ))
3374 }
3375 #[doc = "struct ovs\\_action\\_push\\_eth"]
3376 pub fn get_push_eth(&self) -> Result<&'a [u8], ErrorContext> {
3377 let mut iter = self.clone();
3378 iter.pos = 0;
3379 for attr in iter {
3380 if let ActionAttrs::PushEth(val) = attr? {
3381 return Ok(val);
3382 }
3383 }
3384 Err(ErrorContext::new_missing(
3385 "ActionAttrs",
3386 "PushEth",
3387 self.orig_loc,
3388 self.buf.as_ptr() as usize,
3389 ))
3390 }
3391 pub fn get_pop_eth(&self) -> Result<(), ErrorContext> {
3392 let mut iter = self.clone();
3393 iter.pos = 0;
3394 for attr in iter {
3395 if let ActionAttrs::PopEth(val) = attr? {
3396 return Ok(val);
3397 }
3398 }
3399 Err(ErrorContext::new_missing(
3400 "ActionAttrs",
3401 "PopEth",
3402 self.orig_loc,
3403 self.buf.as_ptr() as usize,
3404 ))
3405 }
3406 pub fn get_ct_clear(&self) -> Result<(), ErrorContext> {
3407 let mut iter = self.clone();
3408 iter.pos = 0;
3409 for attr in iter {
3410 if let ActionAttrs::CtClear(val) = attr? {
3411 return Ok(val);
3412 }
3413 }
3414 Err(ErrorContext::new_missing(
3415 "ActionAttrs",
3416 "CtClear",
3417 self.orig_loc,
3418 self.buf.as_ptr() as usize,
3419 ))
3420 }
3421 #[doc = "Push NSH header to the packet\\.\n"]
3422 pub fn get_push_nsh(&self) -> Result<IterableOvsNshKeyAttrs<'a>, ErrorContext> {
3423 let mut iter = self.clone();
3424 iter.pos = 0;
3425 for attr in iter {
3426 if let ActionAttrs::PushNsh(val) = attr? {
3427 return Ok(val);
3428 }
3429 }
3430 Err(ErrorContext::new_missing(
3431 "ActionAttrs",
3432 "PushNsh",
3433 self.orig_loc,
3434 self.buf.as_ptr() as usize,
3435 ))
3436 }
3437 #[doc = "Pop the outermost NSH header off the packet\\.\n"]
3438 pub fn get_pop_nsh(&self) -> Result<(), ErrorContext> {
3439 let mut iter = self.clone();
3440 iter.pos = 0;
3441 for attr in iter {
3442 if let ActionAttrs::PopNsh(val) = attr? {
3443 return Ok(val);
3444 }
3445 }
3446 Err(ErrorContext::new_missing(
3447 "ActionAttrs",
3448 "PopNsh",
3449 self.orig_loc,
3450 self.buf.as_ptr() as usize,
3451 ))
3452 }
3453 #[doc = "Run packet through a meter, which may drop the packet, or modify the\npacket (e\\.g\\., change the DSCP field)\n"]
3454 pub fn get_meter(&self) -> Result<u32, ErrorContext> {
3455 let mut iter = self.clone();
3456 iter.pos = 0;
3457 for attr in iter {
3458 if let ActionAttrs::Meter(val) = attr? {
3459 return Ok(val);
3460 }
3461 }
3462 Err(ErrorContext::new_missing(
3463 "ActionAttrs",
3464 "Meter",
3465 self.orig_loc,
3466 self.buf.as_ptr() as usize,
3467 ))
3468 }
3469 #[doc = "Make a copy of the packet and execute a list of actions without\naffecting the original packet and key\\.\n"]
3470 pub fn get_clone(&self) -> Result<IterableActionAttrs<'a>, ErrorContext> {
3471 let mut iter = self.clone();
3472 iter.pos = 0;
3473 for attr in iter {
3474 if let ActionAttrs::Clone(val) = attr? {
3475 return Ok(val);
3476 }
3477 }
3478 Err(ErrorContext::new_missing(
3479 "ActionAttrs",
3480 "Clone",
3481 self.orig_loc,
3482 self.buf.as_ptr() as usize,
3483 ))
3484 }
3485 #[doc = "Check the packet length and execute a set of actions if greater than\nthe specified packet length, else execute another set of actions\\.\n"]
3486 pub fn get_check_pkt_len(&self) -> Result<IterableCheckPktLenAttrs<'a>, ErrorContext> {
3487 let mut iter = self.clone();
3488 iter.pos = 0;
3489 for attr in iter {
3490 if let ActionAttrs::CheckPktLen(val) = attr? {
3491 return Ok(val);
3492 }
3493 }
3494 Err(ErrorContext::new_missing(
3495 "ActionAttrs",
3496 "CheckPktLen",
3497 self.orig_loc,
3498 self.buf.as_ptr() as usize,
3499 ))
3500 }
3501 #[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"]
3502 pub fn get_add_mpls(&self) -> Result<OvsActionAddMpls, ErrorContext> {
3503 let mut iter = self.clone();
3504 iter.pos = 0;
3505 for attr in iter {
3506 if let ActionAttrs::AddMpls(val) = attr? {
3507 return Ok(val);
3508 }
3509 }
3510 Err(ErrorContext::new_missing(
3511 "ActionAttrs",
3512 "AddMpls",
3513 self.orig_loc,
3514 self.buf.as_ptr() as usize,
3515 ))
3516 }
3517 pub fn get_dec_ttl(&self) -> Result<IterableDecTtlAttrs<'a>, ErrorContext> {
3518 let mut iter = self.clone();
3519 iter.pos = 0;
3520 for attr in iter {
3521 if let ActionAttrs::DecTtl(val) = attr? {
3522 return Ok(val);
3523 }
3524 }
3525 Err(ErrorContext::new_missing(
3526 "ActionAttrs",
3527 "DecTtl",
3528 self.orig_loc,
3529 self.buf.as_ptr() as usize,
3530 ))
3531 }
3532 #[doc = "Sends a packet sample to psample for external observation\\.\n"]
3533 pub fn get_psample(&self) -> Result<IterablePsampleAttrs<'a>, ErrorContext> {
3534 let mut iter = self.clone();
3535 iter.pos = 0;
3536 for attr in iter {
3537 if let ActionAttrs::Psample(val) = attr? {
3538 return Ok(val);
3539 }
3540 }
3541 Err(ErrorContext::new_missing(
3542 "ActionAttrs",
3543 "Psample",
3544 self.orig_loc,
3545 self.buf.as_ptr() as usize,
3546 ))
3547 }
3548}
3549impl ActionAttrs<'_> {
3550 pub fn new<'a>(buf: &'a [u8]) -> IterableActionAttrs<'a> {
3551 IterableActionAttrs::with_loc(buf, buf.as_ptr() as usize)
3552 }
3553 fn attr_from_type(r#type: u16) -> Option<&'static str> {
3554 let res = match r#type {
3555 1u16 => "Output",
3556 2u16 => "Userspace",
3557 3u16 => "Set",
3558 4u16 => "PushVlan",
3559 5u16 => "PopVlan",
3560 6u16 => "Sample",
3561 7u16 => "Recirc",
3562 8u16 => "Hash",
3563 9u16 => "PushMpls",
3564 10u16 => "PopMpls",
3565 11u16 => "SetMasked",
3566 12u16 => "Ct",
3567 13u16 => "Trunc",
3568 14u16 => "PushEth",
3569 15u16 => "PopEth",
3570 16u16 => "CtClear",
3571 17u16 => "PushNsh",
3572 18u16 => "PopNsh",
3573 19u16 => "Meter",
3574 20u16 => "Clone",
3575 21u16 => "CheckPktLen",
3576 22u16 => "AddMpls",
3577 23u16 => "DecTtl",
3578 24u16 => "Psample",
3579 _ => return None,
3580 };
3581 Some(res)
3582 }
3583}
3584#[derive(Clone, Copy, Default)]
3585pub struct IterableActionAttrs<'a> {
3586 buf: &'a [u8],
3587 pos: usize,
3588 orig_loc: usize,
3589}
3590impl<'a> IterableActionAttrs<'a> {
3591 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
3592 Self {
3593 buf,
3594 pos: 0,
3595 orig_loc,
3596 }
3597 }
3598 pub fn get_buf(&self) -> &'a [u8] {
3599 self.buf
3600 }
3601}
3602impl<'a> Iterator for IterableActionAttrs<'a> {
3603 type Item = Result<ActionAttrs<'a>, ErrorContext>;
3604 fn next(&mut self) -> Option<Self::Item> {
3605 let pos = self.pos;
3606 let mut r#type;
3607 loop {
3608 r#type = None;
3609 if self.buf.len() == self.pos {
3610 return None;
3611 }
3612 let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
3613 break;
3614 };
3615 r#type = Some(header.r#type);
3616 let res = match header.r#type {
3617 1u16 => ActionAttrs::Output({
3618 let res = parse_u32(next);
3619 let Some(val) = res else { break };
3620 val
3621 }),
3622 2u16 => ActionAttrs::Userspace({
3623 let res = Some(IterableUserspaceAttrs::with_loc(next, self.orig_loc));
3624 let Some(val) = res else { break };
3625 val
3626 }),
3627 3u16 => ActionAttrs::Set({
3628 let res = Some(IterableKeyAttrs::with_loc(next, self.orig_loc));
3629 let Some(val) = res else { break };
3630 val
3631 }),
3632 4u16 => ActionAttrs::PushVlan({
3633 let res = Some(OvsActionPushVlan::new_from_zeroed(next));
3634 let Some(val) = res else { break };
3635 val
3636 }),
3637 5u16 => ActionAttrs::PopVlan(()),
3638 6u16 => ActionAttrs::Sample({
3639 let res = Some(IterableSampleAttrs::with_loc(next, self.orig_loc));
3640 let Some(val) = res else { break };
3641 val
3642 }),
3643 7u16 => ActionAttrs::Recirc({
3644 let res = parse_u32(next);
3645 let Some(val) = res else { break };
3646 val
3647 }),
3648 8u16 => ActionAttrs::Hash({
3649 let res = Some(OvsActionHash::new_from_zeroed(next));
3650 let Some(val) = res else { break };
3651 val
3652 }),
3653 9u16 => ActionAttrs::PushMpls({
3654 let res = Some(OvsActionPushMpls::new_from_zeroed(next));
3655 let Some(val) = res else { break };
3656 val
3657 }),
3658 10u16 => ActionAttrs::PopMpls({
3659 let res = parse_be_u16(next);
3660 let Some(val) = res else { break };
3661 val
3662 }),
3663 11u16 => ActionAttrs::SetMasked({
3664 let res = Some(IterableKeyAttrs::with_loc(next, self.orig_loc));
3665 let Some(val) = res else { break };
3666 val
3667 }),
3668 12u16 => ActionAttrs::Ct({
3669 let res = Some(IterableCtAttrs::with_loc(next, self.orig_loc));
3670 let Some(val) = res else { break };
3671 val
3672 }),
3673 13u16 => ActionAttrs::Trunc({
3674 let res = parse_u32(next);
3675 let Some(val) = res else { break };
3676 val
3677 }),
3678 14u16 => ActionAttrs::PushEth({
3679 let res = Some(next);
3680 let Some(val) = res else { break };
3681 val
3682 }),
3683 15u16 => ActionAttrs::PopEth(()),
3684 16u16 => ActionAttrs::CtClear(()),
3685 17u16 => ActionAttrs::PushNsh({
3686 let res = Some(IterableOvsNshKeyAttrs::with_loc(next, self.orig_loc));
3687 let Some(val) = res else { break };
3688 val
3689 }),
3690 18u16 => ActionAttrs::PopNsh(()),
3691 19u16 => ActionAttrs::Meter({
3692 let res = parse_u32(next);
3693 let Some(val) = res else { break };
3694 val
3695 }),
3696 20u16 => ActionAttrs::Clone({
3697 let res = Some(IterableActionAttrs::with_loc(next, self.orig_loc));
3698 let Some(val) = res else { break };
3699 val
3700 }),
3701 21u16 => ActionAttrs::CheckPktLen({
3702 let res = Some(IterableCheckPktLenAttrs::with_loc(next, self.orig_loc));
3703 let Some(val) = res else { break };
3704 val
3705 }),
3706 22u16 => ActionAttrs::AddMpls({
3707 let res = Some(OvsActionAddMpls::new_from_zeroed(next));
3708 let Some(val) = res else { break };
3709 val
3710 }),
3711 23u16 => ActionAttrs::DecTtl({
3712 let res = Some(IterableDecTtlAttrs::with_loc(next, self.orig_loc));
3713 let Some(val) = res else { break };
3714 val
3715 }),
3716 24u16 => ActionAttrs::Psample({
3717 let res = Some(IterablePsampleAttrs::with_loc(next, self.orig_loc));
3718 let Some(val) = res else { break };
3719 val
3720 }),
3721 n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
3722 n => continue,
3723 };
3724 return Some(Ok(res));
3725 }
3726 Some(Err(ErrorContext::new(
3727 "ActionAttrs",
3728 r#type.and_then(|t| ActionAttrs::attr_from_type(t)),
3729 self.orig_loc,
3730 self.buf.as_ptr().wrapping_add(pos) as usize,
3731 )))
3732 }
3733}
3734impl<'a> std::fmt::Debug for IterableActionAttrs<'_> {
3735 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3736 let mut fmt = f.debug_struct("ActionAttrs");
3737 for attr in self.clone() {
3738 let attr = match attr {
3739 Ok(a) => a,
3740 Err(err) => {
3741 fmt.finish()?;
3742 f.write_str("Err(")?;
3743 err.fmt(f)?;
3744 return f.write_str(")");
3745 }
3746 };
3747 match attr {
3748 ActionAttrs::Output(val) => fmt.field("Output", &val),
3749 ActionAttrs::Userspace(val) => fmt.field("Userspace", &val),
3750 ActionAttrs::Set(val) => fmt.field("Set", &val),
3751 ActionAttrs::PushVlan(val) => fmt.field("PushVlan", &val),
3752 ActionAttrs::PopVlan(val) => fmt.field("PopVlan", &val),
3753 ActionAttrs::Sample(val) => fmt.field("Sample", &val),
3754 ActionAttrs::Recirc(val) => fmt.field("Recirc", &val),
3755 ActionAttrs::Hash(val) => fmt.field("Hash", &val),
3756 ActionAttrs::PushMpls(val) => fmt.field("PushMpls", &val),
3757 ActionAttrs::PopMpls(val) => fmt.field("PopMpls", &val),
3758 ActionAttrs::SetMasked(val) => fmt.field("SetMasked", &val),
3759 ActionAttrs::Ct(val) => fmt.field("Ct", &val),
3760 ActionAttrs::Trunc(val) => fmt.field("Trunc", &val),
3761 ActionAttrs::PushEth(val) => fmt.field("PushEth", &val),
3762 ActionAttrs::PopEth(val) => fmt.field("PopEth", &val),
3763 ActionAttrs::CtClear(val) => fmt.field("CtClear", &val),
3764 ActionAttrs::PushNsh(val) => fmt.field("PushNsh", &val),
3765 ActionAttrs::PopNsh(val) => fmt.field("PopNsh", &val),
3766 ActionAttrs::Meter(val) => fmt.field("Meter", &val),
3767 ActionAttrs::Clone(val) => fmt.field("Clone", &val),
3768 ActionAttrs::CheckPktLen(val) => fmt.field("CheckPktLen", &val),
3769 ActionAttrs::AddMpls(val) => fmt.field("AddMpls", &val),
3770 ActionAttrs::DecTtl(val) => fmt.field("DecTtl", &val),
3771 ActionAttrs::Psample(val) => fmt.field("Psample", &val),
3772 };
3773 }
3774 fmt.finish()
3775 }
3776}
3777impl IterableActionAttrs<'_> {
3778 pub fn lookup_attr(
3779 &self,
3780 offset: usize,
3781 missing_type: Option<u16>,
3782 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
3783 let mut stack = Vec::new();
3784 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
3785 if missing_type.is_some() && cur == offset {
3786 stack.push(("ActionAttrs", offset));
3787 return (
3788 stack,
3789 missing_type.and_then(|t| ActionAttrs::attr_from_type(t)),
3790 );
3791 }
3792 if cur > offset || cur + self.buf.len() < offset {
3793 return (stack, None);
3794 }
3795 let mut attrs = self.clone();
3796 let mut last_off = cur + attrs.pos;
3797 let mut missing = None;
3798 while let Some(attr) = attrs.next() {
3799 let Ok(attr) = attr else { break };
3800 match attr {
3801 ActionAttrs::Output(val) => {
3802 if last_off == offset {
3803 stack.push(("Output", last_off));
3804 break;
3805 }
3806 }
3807 ActionAttrs::Userspace(val) => {
3808 (stack, missing) = val.lookup_attr(offset, missing_type);
3809 if !stack.is_empty() {
3810 break;
3811 }
3812 }
3813 ActionAttrs::Set(val) => {
3814 (stack, missing) = val.lookup_attr(offset, missing_type);
3815 if !stack.is_empty() {
3816 break;
3817 }
3818 }
3819 ActionAttrs::PushVlan(val) => {
3820 if last_off == offset {
3821 stack.push(("PushVlan", last_off));
3822 break;
3823 }
3824 }
3825 ActionAttrs::PopVlan(val) => {
3826 if last_off == offset {
3827 stack.push(("PopVlan", last_off));
3828 break;
3829 }
3830 }
3831 ActionAttrs::Sample(val) => {
3832 (stack, missing) = val.lookup_attr(offset, missing_type);
3833 if !stack.is_empty() {
3834 break;
3835 }
3836 }
3837 ActionAttrs::Recirc(val) => {
3838 if last_off == offset {
3839 stack.push(("Recirc", last_off));
3840 break;
3841 }
3842 }
3843 ActionAttrs::Hash(val) => {
3844 if last_off == offset {
3845 stack.push(("Hash", last_off));
3846 break;
3847 }
3848 }
3849 ActionAttrs::PushMpls(val) => {
3850 if last_off == offset {
3851 stack.push(("PushMpls", last_off));
3852 break;
3853 }
3854 }
3855 ActionAttrs::PopMpls(val) => {
3856 if last_off == offset {
3857 stack.push(("PopMpls", last_off));
3858 break;
3859 }
3860 }
3861 ActionAttrs::SetMasked(val) => {
3862 (stack, missing) = val.lookup_attr(offset, missing_type);
3863 if !stack.is_empty() {
3864 break;
3865 }
3866 }
3867 ActionAttrs::Ct(val) => {
3868 (stack, missing) = val.lookup_attr(offset, missing_type);
3869 if !stack.is_empty() {
3870 break;
3871 }
3872 }
3873 ActionAttrs::Trunc(val) => {
3874 if last_off == offset {
3875 stack.push(("Trunc", last_off));
3876 break;
3877 }
3878 }
3879 ActionAttrs::PushEth(val) => {
3880 if last_off == offset {
3881 stack.push(("PushEth", last_off));
3882 break;
3883 }
3884 }
3885 ActionAttrs::PopEth(val) => {
3886 if last_off == offset {
3887 stack.push(("PopEth", last_off));
3888 break;
3889 }
3890 }
3891 ActionAttrs::CtClear(val) => {
3892 if last_off == offset {
3893 stack.push(("CtClear", last_off));
3894 break;
3895 }
3896 }
3897 ActionAttrs::PushNsh(val) => {
3898 (stack, missing) = val.lookup_attr(offset, missing_type);
3899 if !stack.is_empty() {
3900 break;
3901 }
3902 }
3903 ActionAttrs::PopNsh(val) => {
3904 if last_off == offset {
3905 stack.push(("PopNsh", last_off));
3906 break;
3907 }
3908 }
3909 ActionAttrs::Meter(val) => {
3910 if last_off == offset {
3911 stack.push(("Meter", last_off));
3912 break;
3913 }
3914 }
3915 ActionAttrs::Clone(val) => {
3916 (stack, missing) = val.lookup_attr(offset, missing_type);
3917 if !stack.is_empty() {
3918 break;
3919 }
3920 }
3921 ActionAttrs::CheckPktLen(val) => {
3922 (stack, missing) = val.lookup_attr(offset, missing_type);
3923 if !stack.is_empty() {
3924 break;
3925 }
3926 }
3927 ActionAttrs::AddMpls(val) => {
3928 if last_off == offset {
3929 stack.push(("AddMpls", last_off));
3930 break;
3931 }
3932 }
3933 ActionAttrs::DecTtl(val) => {
3934 (stack, missing) = val.lookup_attr(offset, missing_type);
3935 if !stack.is_empty() {
3936 break;
3937 }
3938 }
3939 ActionAttrs::Psample(val) => {
3940 (stack, missing) = val.lookup_attr(offset, missing_type);
3941 if !stack.is_empty() {
3942 break;
3943 }
3944 }
3945 _ => {}
3946 };
3947 last_off = cur + attrs.pos;
3948 }
3949 if !stack.is_empty() {
3950 stack.push(("ActionAttrs", cur));
3951 }
3952 (stack, missing)
3953 }
3954}
3955#[derive(Clone)]
3956pub enum TunnelKeyAttrs<'a> {
3957 Id(u64),
3958 Ipv4Src(u32),
3959 Ipv4Dst(u32),
3960 Tos(u8),
3961 Ttl(u8),
3962 DontFragment(()),
3963 Csum(()),
3964 Oam(()),
3965 GeneveOpts(&'a [u8]),
3966 TpSrc(u16),
3967 TpDst(u16),
3968 VxlanOpts(IterableVxlanExtAttrs<'a>),
3969 #[doc = "struct in6\\_addr source IPv6 address\n"]
3970 Ipv6Src(&'a [u8]),
3971 #[doc = "struct in6\\_addr destination IPv6 address\n"]
3972 Ipv6Dst(&'a [u8]),
3973 Pad(&'a [u8]),
3974 #[doc = "struct erspan\\_metadata\n"]
3975 ErspanOpts(&'a [u8]),
3976 Ipv4InfoBridge(()),
3977}
3978impl<'a> IterableTunnelKeyAttrs<'a> {
3979 pub fn get_id(&self) -> Result<u64, ErrorContext> {
3980 let mut iter = self.clone();
3981 iter.pos = 0;
3982 for attr in iter {
3983 if let TunnelKeyAttrs::Id(val) = attr? {
3984 return Ok(val);
3985 }
3986 }
3987 Err(ErrorContext::new_missing(
3988 "TunnelKeyAttrs",
3989 "Id",
3990 self.orig_loc,
3991 self.buf.as_ptr() as usize,
3992 ))
3993 }
3994 pub fn get_ipv4_src(&self) -> Result<u32, ErrorContext> {
3995 let mut iter = self.clone();
3996 iter.pos = 0;
3997 for attr in iter {
3998 if let TunnelKeyAttrs::Ipv4Src(val) = attr? {
3999 return Ok(val);
4000 }
4001 }
4002 Err(ErrorContext::new_missing(
4003 "TunnelKeyAttrs",
4004 "Ipv4Src",
4005 self.orig_loc,
4006 self.buf.as_ptr() as usize,
4007 ))
4008 }
4009 pub fn get_ipv4_dst(&self) -> Result<u32, ErrorContext> {
4010 let mut iter = self.clone();
4011 iter.pos = 0;
4012 for attr in iter {
4013 if let TunnelKeyAttrs::Ipv4Dst(val) = attr? {
4014 return Ok(val);
4015 }
4016 }
4017 Err(ErrorContext::new_missing(
4018 "TunnelKeyAttrs",
4019 "Ipv4Dst",
4020 self.orig_loc,
4021 self.buf.as_ptr() as usize,
4022 ))
4023 }
4024 pub fn get_tos(&self) -> Result<u8, ErrorContext> {
4025 let mut iter = self.clone();
4026 iter.pos = 0;
4027 for attr in iter {
4028 if let TunnelKeyAttrs::Tos(val) = attr? {
4029 return Ok(val);
4030 }
4031 }
4032 Err(ErrorContext::new_missing(
4033 "TunnelKeyAttrs",
4034 "Tos",
4035 self.orig_loc,
4036 self.buf.as_ptr() as usize,
4037 ))
4038 }
4039 pub fn get_ttl(&self) -> Result<u8, ErrorContext> {
4040 let mut iter = self.clone();
4041 iter.pos = 0;
4042 for attr in iter {
4043 if let TunnelKeyAttrs::Ttl(val) = attr? {
4044 return Ok(val);
4045 }
4046 }
4047 Err(ErrorContext::new_missing(
4048 "TunnelKeyAttrs",
4049 "Ttl",
4050 self.orig_loc,
4051 self.buf.as_ptr() as usize,
4052 ))
4053 }
4054 pub fn get_dont_fragment(&self) -> Result<(), ErrorContext> {
4055 let mut iter = self.clone();
4056 iter.pos = 0;
4057 for attr in iter {
4058 if let TunnelKeyAttrs::DontFragment(val) = attr? {
4059 return Ok(val);
4060 }
4061 }
4062 Err(ErrorContext::new_missing(
4063 "TunnelKeyAttrs",
4064 "DontFragment",
4065 self.orig_loc,
4066 self.buf.as_ptr() as usize,
4067 ))
4068 }
4069 pub fn get_csum(&self) -> Result<(), ErrorContext> {
4070 let mut iter = self.clone();
4071 iter.pos = 0;
4072 for attr in iter {
4073 if let TunnelKeyAttrs::Csum(val) = attr? {
4074 return Ok(val);
4075 }
4076 }
4077 Err(ErrorContext::new_missing(
4078 "TunnelKeyAttrs",
4079 "Csum",
4080 self.orig_loc,
4081 self.buf.as_ptr() as usize,
4082 ))
4083 }
4084 pub fn get_oam(&self) -> Result<(), ErrorContext> {
4085 let mut iter = self.clone();
4086 iter.pos = 0;
4087 for attr in iter {
4088 if let TunnelKeyAttrs::Oam(val) = attr? {
4089 return Ok(val);
4090 }
4091 }
4092 Err(ErrorContext::new_missing(
4093 "TunnelKeyAttrs",
4094 "Oam",
4095 self.orig_loc,
4096 self.buf.as_ptr() as usize,
4097 ))
4098 }
4099 pub fn get_geneve_opts(&self) -> Result<&'a [u8], ErrorContext> {
4100 let mut iter = self.clone();
4101 iter.pos = 0;
4102 for attr in iter {
4103 if let TunnelKeyAttrs::GeneveOpts(val) = attr? {
4104 return Ok(val);
4105 }
4106 }
4107 Err(ErrorContext::new_missing(
4108 "TunnelKeyAttrs",
4109 "GeneveOpts",
4110 self.orig_loc,
4111 self.buf.as_ptr() as usize,
4112 ))
4113 }
4114 pub fn get_tp_src(&self) -> Result<u16, ErrorContext> {
4115 let mut iter = self.clone();
4116 iter.pos = 0;
4117 for attr in iter {
4118 if let TunnelKeyAttrs::TpSrc(val) = attr? {
4119 return Ok(val);
4120 }
4121 }
4122 Err(ErrorContext::new_missing(
4123 "TunnelKeyAttrs",
4124 "TpSrc",
4125 self.orig_loc,
4126 self.buf.as_ptr() as usize,
4127 ))
4128 }
4129 pub fn get_tp_dst(&self) -> Result<u16, ErrorContext> {
4130 let mut iter = self.clone();
4131 iter.pos = 0;
4132 for attr in iter {
4133 if let TunnelKeyAttrs::TpDst(val) = attr? {
4134 return Ok(val);
4135 }
4136 }
4137 Err(ErrorContext::new_missing(
4138 "TunnelKeyAttrs",
4139 "TpDst",
4140 self.orig_loc,
4141 self.buf.as_ptr() as usize,
4142 ))
4143 }
4144 pub fn get_vxlan_opts(&self) -> Result<IterableVxlanExtAttrs<'a>, ErrorContext> {
4145 let mut iter = self.clone();
4146 iter.pos = 0;
4147 for attr in iter {
4148 if let TunnelKeyAttrs::VxlanOpts(val) = attr? {
4149 return Ok(val);
4150 }
4151 }
4152 Err(ErrorContext::new_missing(
4153 "TunnelKeyAttrs",
4154 "VxlanOpts",
4155 self.orig_loc,
4156 self.buf.as_ptr() as usize,
4157 ))
4158 }
4159 #[doc = "struct in6\\_addr source IPv6 address\n"]
4160 pub fn get_ipv6_src(&self) -> Result<&'a [u8], ErrorContext> {
4161 let mut iter = self.clone();
4162 iter.pos = 0;
4163 for attr in iter {
4164 if let TunnelKeyAttrs::Ipv6Src(val) = attr? {
4165 return Ok(val);
4166 }
4167 }
4168 Err(ErrorContext::new_missing(
4169 "TunnelKeyAttrs",
4170 "Ipv6Src",
4171 self.orig_loc,
4172 self.buf.as_ptr() as usize,
4173 ))
4174 }
4175 #[doc = "struct in6\\_addr destination IPv6 address\n"]
4176 pub fn get_ipv6_dst(&self) -> Result<&'a [u8], ErrorContext> {
4177 let mut iter = self.clone();
4178 iter.pos = 0;
4179 for attr in iter {
4180 if let TunnelKeyAttrs::Ipv6Dst(val) = attr? {
4181 return Ok(val);
4182 }
4183 }
4184 Err(ErrorContext::new_missing(
4185 "TunnelKeyAttrs",
4186 "Ipv6Dst",
4187 self.orig_loc,
4188 self.buf.as_ptr() as usize,
4189 ))
4190 }
4191 pub fn get_pad(&self) -> Result<&'a [u8], ErrorContext> {
4192 let mut iter = self.clone();
4193 iter.pos = 0;
4194 for attr in iter {
4195 if let TunnelKeyAttrs::Pad(val) = attr? {
4196 return Ok(val);
4197 }
4198 }
4199 Err(ErrorContext::new_missing(
4200 "TunnelKeyAttrs",
4201 "Pad",
4202 self.orig_loc,
4203 self.buf.as_ptr() as usize,
4204 ))
4205 }
4206 #[doc = "struct erspan\\_metadata\n"]
4207 pub fn get_erspan_opts(&self) -> Result<&'a [u8], ErrorContext> {
4208 let mut iter = self.clone();
4209 iter.pos = 0;
4210 for attr in iter {
4211 if let TunnelKeyAttrs::ErspanOpts(val) = attr? {
4212 return Ok(val);
4213 }
4214 }
4215 Err(ErrorContext::new_missing(
4216 "TunnelKeyAttrs",
4217 "ErspanOpts",
4218 self.orig_loc,
4219 self.buf.as_ptr() as usize,
4220 ))
4221 }
4222 pub fn get_ipv4_info_bridge(&self) -> Result<(), ErrorContext> {
4223 let mut iter = self.clone();
4224 iter.pos = 0;
4225 for attr in iter {
4226 if let TunnelKeyAttrs::Ipv4InfoBridge(val) = attr? {
4227 return Ok(val);
4228 }
4229 }
4230 Err(ErrorContext::new_missing(
4231 "TunnelKeyAttrs",
4232 "Ipv4InfoBridge",
4233 self.orig_loc,
4234 self.buf.as_ptr() as usize,
4235 ))
4236 }
4237}
4238impl TunnelKeyAttrs<'_> {
4239 pub fn new<'a>(buf: &'a [u8]) -> IterableTunnelKeyAttrs<'a> {
4240 IterableTunnelKeyAttrs::with_loc(buf, buf.as_ptr() as usize)
4241 }
4242 fn attr_from_type(r#type: u16) -> Option<&'static str> {
4243 let res = match r#type {
4244 0u16 => "Id",
4245 1u16 => "Ipv4Src",
4246 2u16 => "Ipv4Dst",
4247 3u16 => "Tos",
4248 4u16 => "Ttl",
4249 5u16 => "DontFragment",
4250 6u16 => "Csum",
4251 7u16 => "Oam",
4252 8u16 => "GeneveOpts",
4253 9u16 => "TpSrc",
4254 10u16 => "TpDst",
4255 11u16 => "VxlanOpts",
4256 12u16 => "Ipv6Src",
4257 13u16 => "Ipv6Dst",
4258 14u16 => "Pad",
4259 15u16 => "ErspanOpts",
4260 16u16 => "Ipv4InfoBridge",
4261 _ => return None,
4262 };
4263 Some(res)
4264 }
4265}
4266#[derive(Clone, Copy, Default)]
4267pub struct IterableTunnelKeyAttrs<'a> {
4268 buf: &'a [u8],
4269 pos: usize,
4270 orig_loc: usize,
4271}
4272impl<'a> IterableTunnelKeyAttrs<'a> {
4273 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
4274 Self {
4275 buf,
4276 pos: 0,
4277 orig_loc,
4278 }
4279 }
4280 pub fn get_buf(&self) -> &'a [u8] {
4281 self.buf
4282 }
4283}
4284impl<'a> Iterator for IterableTunnelKeyAttrs<'a> {
4285 type Item = Result<TunnelKeyAttrs<'a>, ErrorContext>;
4286 fn next(&mut self) -> Option<Self::Item> {
4287 let pos = self.pos;
4288 let mut r#type;
4289 loop {
4290 r#type = None;
4291 if self.buf.len() == self.pos {
4292 return None;
4293 }
4294 let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
4295 break;
4296 };
4297 r#type = Some(header.r#type);
4298 let res = match header.r#type {
4299 0u16 => TunnelKeyAttrs::Id({
4300 let res = parse_be_u64(next);
4301 let Some(val) = res else { break };
4302 val
4303 }),
4304 1u16 => TunnelKeyAttrs::Ipv4Src({
4305 let res = parse_be_u32(next);
4306 let Some(val) = res else { break };
4307 val
4308 }),
4309 2u16 => TunnelKeyAttrs::Ipv4Dst({
4310 let res = parse_be_u32(next);
4311 let Some(val) = res else { break };
4312 val
4313 }),
4314 3u16 => TunnelKeyAttrs::Tos({
4315 let res = parse_u8(next);
4316 let Some(val) = res else { break };
4317 val
4318 }),
4319 4u16 => TunnelKeyAttrs::Ttl({
4320 let res = parse_u8(next);
4321 let Some(val) = res else { break };
4322 val
4323 }),
4324 5u16 => TunnelKeyAttrs::DontFragment(()),
4325 6u16 => TunnelKeyAttrs::Csum(()),
4326 7u16 => TunnelKeyAttrs::Oam(()),
4327 8u16 => TunnelKeyAttrs::GeneveOpts({
4328 let res = Some(next);
4329 let Some(val) = res else { break };
4330 val
4331 }),
4332 9u16 => TunnelKeyAttrs::TpSrc({
4333 let res = parse_be_u16(next);
4334 let Some(val) = res else { break };
4335 val
4336 }),
4337 10u16 => TunnelKeyAttrs::TpDst({
4338 let res = parse_be_u16(next);
4339 let Some(val) = res else { break };
4340 val
4341 }),
4342 11u16 => TunnelKeyAttrs::VxlanOpts({
4343 let res = Some(IterableVxlanExtAttrs::with_loc(next, self.orig_loc));
4344 let Some(val) = res else { break };
4345 val
4346 }),
4347 12u16 => TunnelKeyAttrs::Ipv6Src({
4348 let res = Some(next);
4349 let Some(val) = res else { break };
4350 val
4351 }),
4352 13u16 => TunnelKeyAttrs::Ipv6Dst({
4353 let res = Some(next);
4354 let Some(val) = res else { break };
4355 val
4356 }),
4357 14u16 => TunnelKeyAttrs::Pad({
4358 let res = Some(next);
4359 let Some(val) = res else { break };
4360 val
4361 }),
4362 15u16 => TunnelKeyAttrs::ErspanOpts({
4363 let res = Some(next);
4364 let Some(val) = res else { break };
4365 val
4366 }),
4367 16u16 => TunnelKeyAttrs::Ipv4InfoBridge(()),
4368 n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
4369 n => continue,
4370 };
4371 return Some(Ok(res));
4372 }
4373 Some(Err(ErrorContext::new(
4374 "TunnelKeyAttrs",
4375 r#type.and_then(|t| TunnelKeyAttrs::attr_from_type(t)),
4376 self.orig_loc,
4377 self.buf.as_ptr().wrapping_add(pos) as usize,
4378 )))
4379 }
4380}
4381impl<'a> std::fmt::Debug for IterableTunnelKeyAttrs<'_> {
4382 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
4383 let mut fmt = f.debug_struct("TunnelKeyAttrs");
4384 for attr in self.clone() {
4385 let attr = match attr {
4386 Ok(a) => a,
4387 Err(err) => {
4388 fmt.finish()?;
4389 f.write_str("Err(")?;
4390 err.fmt(f)?;
4391 return f.write_str(")");
4392 }
4393 };
4394 match attr {
4395 TunnelKeyAttrs::Id(val) => fmt.field("Id", &val),
4396 TunnelKeyAttrs::Ipv4Src(val) => fmt.field("Ipv4Src", &val),
4397 TunnelKeyAttrs::Ipv4Dst(val) => fmt.field("Ipv4Dst", &val),
4398 TunnelKeyAttrs::Tos(val) => fmt.field("Tos", &val),
4399 TunnelKeyAttrs::Ttl(val) => fmt.field("Ttl", &val),
4400 TunnelKeyAttrs::DontFragment(val) => fmt.field("DontFragment", &val),
4401 TunnelKeyAttrs::Csum(val) => fmt.field("Csum", &val),
4402 TunnelKeyAttrs::Oam(val) => fmt.field("Oam", &val),
4403 TunnelKeyAttrs::GeneveOpts(val) => fmt.field("GeneveOpts", &val),
4404 TunnelKeyAttrs::TpSrc(val) => fmt.field("TpSrc", &val),
4405 TunnelKeyAttrs::TpDst(val) => fmt.field("TpDst", &val),
4406 TunnelKeyAttrs::VxlanOpts(val) => fmt.field("VxlanOpts", &val),
4407 TunnelKeyAttrs::Ipv6Src(val) => fmt.field("Ipv6Src", &val),
4408 TunnelKeyAttrs::Ipv6Dst(val) => fmt.field("Ipv6Dst", &val),
4409 TunnelKeyAttrs::Pad(val) => fmt.field("Pad", &val),
4410 TunnelKeyAttrs::ErspanOpts(val) => fmt.field("ErspanOpts", &val),
4411 TunnelKeyAttrs::Ipv4InfoBridge(val) => fmt.field("Ipv4InfoBridge", &val),
4412 };
4413 }
4414 fmt.finish()
4415 }
4416}
4417impl IterableTunnelKeyAttrs<'_> {
4418 pub fn lookup_attr(
4419 &self,
4420 offset: usize,
4421 missing_type: Option<u16>,
4422 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
4423 let mut stack = Vec::new();
4424 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
4425 if missing_type.is_some() && cur == offset {
4426 stack.push(("TunnelKeyAttrs", offset));
4427 return (
4428 stack,
4429 missing_type.and_then(|t| TunnelKeyAttrs::attr_from_type(t)),
4430 );
4431 }
4432 if cur > offset || cur + self.buf.len() < offset {
4433 return (stack, None);
4434 }
4435 let mut attrs = self.clone();
4436 let mut last_off = cur + attrs.pos;
4437 let mut missing = None;
4438 while let Some(attr) = attrs.next() {
4439 let Ok(attr) = attr else { break };
4440 match attr {
4441 TunnelKeyAttrs::Id(val) => {
4442 if last_off == offset {
4443 stack.push(("Id", last_off));
4444 break;
4445 }
4446 }
4447 TunnelKeyAttrs::Ipv4Src(val) => {
4448 if last_off == offset {
4449 stack.push(("Ipv4Src", last_off));
4450 break;
4451 }
4452 }
4453 TunnelKeyAttrs::Ipv4Dst(val) => {
4454 if last_off == offset {
4455 stack.push(("Ipv4Dst", last_off));
4456 break;
4457 }
4458 }
4459 TunnelKeyAttrs::Tos(val) => {
4460 if last_off == offset {
4461 stack.push(("Tos", last_off));
4462 break;
4463 }
4464 }
4465 TunnelKeyAttrs::Ttl(val) => {
4466 if last_off == offset {
4467 stack.push(("Ttl", last_off));
4468 break;
4469 }
4470 }
4471 TunnelKeyAttrs::DontFragment(val) => {
4472 if last_off == offset {
4473 stack.push(("DontFragment", last_off));
4474 break;
4475 }
4476 }
4477 TunnelKeyAttrs::Csum(val) => {
4478 if last_off == offset {
4479 stack.push(("Csum", last_off));
4480 break;
4481 }
4482 }
4483 TunnelKeyAttrs::Oam(val) => {
4484 if last_off == offset {
4485 stack.push(("Oam", last_off));
4486 break;
4487 }
4488 }
4489 TunnelKeyAttrs::GeneveOpts(val) => {
4490 if last_off == offset {
4491 stack.push(("GeneveOpts", last_off));
4492 break;
4493 }
4494 }
4495 TunnelKeyAttrs::TpSrc(val) => {
4496 if last_off == offset {
4497 stack.push(("TpSrc", last_off));
4498 break;
4499 }
4500 }
4501 TunnelKeyAttrs::TpDst(val) => {
4502 if last_off == offset {
4503 stack.push(("TpDst", last_off));
4504 break;
4505 }
4506 }
4507 TunnelKeyAttrs::VxlanOpts(val) => {
4508 (stack, missing) = val.lookup_attr(offset, missing_type);
4509 if !stack.is_empty() {
4510 break;
4511 }
4512 }
4513 TunnelKeyAttrs::Ipv6Src(val) => {
4514 if last_off == offset {
4515 stack.push(("Ipv6Src", last_off));
4516 break;
4517 }
4518 }
4519 TunnelKeyAttrs::Ipv6Dst(val) => {
4520 if last_off == offset {
4521 stack.push(("Ipv6Dst", last_off));
4522 break;
4523 }
4524 }
4525 TunnelKeyAttrs::Pad(val) => {
4526 if last_off == offset {
4527 stack.push(("Pad", last_off));
4528 break;
4529 }
4530 }
4531 TunnelKeyAttrs::ErspanOpts(val) => {
4532 if last_off == offset {
4533 stack.push(("ErspanOpts", last_off));
4534 break;
4535 }
4536 }
4537 TunnelKeyAttrs::Ipv4InfoBridge(val) => {
4538 if last_off == offset {
4539 stack.push(("Ipv4InfoBridge", last_off));
4540 break;
4541 }
4542 }
4543 _ => {}
4544 };
4545 last_off = cur + attrs.pos;
4546 }
4547 if !stack.is_empty() {
4548 stack.push(("TunnelKeyAttrs", cur));
4549 }
4550 (stack, missing)
4551 }
4552}
4553#[derive(Clone)]
4554pub enum CheckPktLenAttrs<'a> {
4555 PktLen(u16),
4556 ActionsIfGreater(IterableActionAttrs<'a>),
4557 ActionsIfLessEqual(IterableActionAttrs<'a>),
4558}
4559impl<'a> IterableCheckPktLenAttrs<'a> {
4560 pub fn get_pkt_len(&self) -> Result<u16, ErrorContext> {
4561 let mut iter = self.clone();
4562 iter.pos = 0;
4563 for attr in iter {
4564 if let CheckPktLenAttrs::PktLen(val) = attr? {
4565 return Ok(val);
4566 }
4567 }
4568 Err(ErrorContext::new_missing(
4569 "CheckPktLenAttrs",
4570 "PktLen",
4571 self.orig_loc,
4572 self.buf.as_ptr() as usize,
4573 ))
4574 }
4575 pub fn get_actions_if_greater(&self) -> Result<IterableActionAttrs<'a>, ErrorContext> {
4576 let mut iter = self.clone();
4577 iter.pos = 0;
4578 for attr in iter {
4579 if let CheckPktLenAttrs::ActionsIfGreater(val) = attr? {
4580 return Ok(val);
4581 }
4582 }
4583 Err(ErrorContext::new_missing(
4584 "CheckPktLenAttrs",
4585 "ActionsIfGreater",
4586 self.orig_loc,
4587 self.buf.as_ptr() as usize,
4588 ))
4589 }
4590 pub fn get_actions_if_less_equal(&self) -> Result<IterableActionAttrs<'a>, ErrorContext> {
4591 let mut iter = self.clone();
4592 iter.pos = 0;
4593 for attr in iter {
4594 if let CheckPktLenAttrs::ActionsIfLessEqual(val) = attr? {
4595 return Ok(val);
4596 }
4597 }
4598 Err(ErrorContext::new_missing(
4599 "CheckPktLenAttrs",
4600 "ActionsIfLessEqual",
4601 self.orig_loc,
4602 self.buf.as_ptr() as usize,
4603 ))
4604 }
4605}
4606impl CheckPktLenAttrs<'_> {
4607 pub fn new<'a>(buf: &'a [u8]) -> IterableCheckPktLenAttrs<'a> {
4608 IterableCheckPktLenAttrs::with_loc(buf, buf.as_ptr() as usize)
4609 }
4610 fn attr_from_type(r#type: u16) -> Option<&'static str> {
4611 let res = match r#type {
4612 1u16 => "PktLen",
4613 2u16 => "ActionsIfGreater",
4614 3u16 => "ActionsIfLessEqual",
4615 _ => return None,
4616 };
4617 Some(res)
4618 }
4619}
4620#[derive(Clone, Copy, Default)]
4621pub struct IterableCheckPktLenAttrs<'a> {
4622 buf: &'a [u8],
4623 pos: usize,
4624 orig_loc: usize,
4625}
4626impl<'a> IterableCheckPktLenAttrs<'a> {
4627 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
4628 Self {
4629 buf,
4630 pos: 0,
4631 orig_loc,
4632 }
4633 }
4634 pub fn get_buf(&self) -> &'a [u8] {
4635 self.buf
4636 }
4637}
4638impl<'a> Iterator for IterableCheckPktLenAttrs<'a> {
4639 type Item = Result<CheckPktLenAttrs<'a>, ErrorContext>;
4640 fn next(&mut self) -> Option<Self::Item> {
4641 let pos = self.pos;
4642 let mut r#type;
4643 loop {
4644 r#type = None;
4645 if self.buf.len() == self.pos {
4646 return None;
4647 }
4648 let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
4649 break;
4650 };
4651 r#type = Some(header.r#type);
4652 let res = match header.r#type {
4653 1u16 => CheckPktLenAttrs::PktLen({
4654 let res = parse_u16(next);
4655 let Some(val) = res else { break };
4656 val
4657 }),
4658 2u16 => CheckPktLenAttrs::ActionsIfGreater({
4659 let res = Some(IterableActionAttrs::with_loc(next, self.orig_loc));
4660 let Some(val) = res else { break };
4661 val
4662 }),
4663 3u16 => CheckPktLenAttrs::ActionsIfLessEqual({
4664 let res = Some(IterableActionAttrs::with_loc(next, self.orig_loc));
4665 let Some(val) = res else { break };
4666 val
4667 }),
4668 n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
4669 n => continue,
4670 };
4671 return Some(Ok(res));
4672 }
4673 Some(Err(ErrorContext::new(
4674 "CheckPktLenAttrs",
4675 r#type.and_then(|t| CheckPktLenAttrs::attr_from_type(t)),
4676 self.orig_loc,
4677 self.buf.as_ptr().wrapping_add(pos) as usize,
4678 )))
4679 }
4680}
4681impl<'a> std::fmt::Debug for IterableCheckPktLenAttrs<'_> {
4682 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
4683 let mut fmt = f.debug_struct("CheckPktLenAttrs");
4684 for attr in self.clone() {
4685 let attr = match attr {
4686 Ok(a) => a,
4687 Err(err) => {
4688 fmt.finish()?;
4689 f.write_str("Err(")?;
4690 err.fmt(f)?;
4691 return f.write_str(")");
4692 }
4693 };
4694 match attr {
4695 CheckPktLenAttrs::PktLen(val) => fmt.field("PktLen", &val),
4696 CheckPktLenAttrs::ActionsIfGreater(val) => fmt.field("ActionsIfGreater", &val),
4697 CheckPktLenAttrs::ActionsIfLessEqual(val) => fmt.field("ActionsIfLessEqual", &val),
4698 };
4699 }
4700 fmt.finish()
4701 }
4702}
4703impl IterableCheckPktLenAttrs<'_> {
4704 pub fn lookup_attr(
4705 &self,
4706 offset: usize,
4707 missing_type: Option<u16>,
4708 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
4709 let mut stack = Vec::new();
4710 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
4711 if missing_type.is_some() && cur == offset {
4712 stack.push(("CheckPktLenAttrs", offset));
4713 return (
4714 stack,
4715 missing_type.and_then(|t| CheckPktLenAttrs::attr_from_type(t)),
4716 );
4717 }
4718 if cur > offset || cur + self.buf.len() < offset {
4719 return (stack, None);
4720 }
4721 let mut attrs = self.clone();
4722 let mut last_off = cur + attrs.pos;
4723 let mut missing = None;
4724 while let Some(attr) = attrs.next() {
4725 let Ok(attr) = attr else { break };
4726 match attr {
4727 CheckPktLenAttrs::PktLen(val) => {
4728 if last_off == offset {
4729 stack.push(("PktLen", last_off));
4730 break;
4731 }
4732 }
4733 CheckPktLenAttrs::ActionsIfGreater(val) => {
4734 (stack, missing) = val.lookup_attr(offset, missing_type);
4735 if !stack.is_empty() {
4736 break;
4737 }
4738 }
4739 CheckPktLenAttrs::ActionsIfLessEqual(val) => {
4740 (stack, missing) = val.lookup_attr(offset, missing_type);
4741 if !stack.is_empty() {
4742 break;
4743 }
4744 }
4745 _ => {}
4746 };
4747 last_off = cur + attrs.pos;
4748 }
4749 if !stack.is_empty() {
4750 stack.push(("CheckPktLenAttrs", cur));
4751 }
4752 (stack, missing)
4753 }
4754}
4755#[derive(Clone)]
4756pub enum SampleAttrs<'a> {
4757 Probability(u32),
4758 Actions(IterableActionAttrs<'a>),
4759}
4760impl<'a> IterableSampleAttrs<'a> {
4761 pub fn get_probability(&self) -> Result<u32, ErrorContext> {
4762 let mut iter = self.clone();
4763 iter.pos = 0;
4764 for attr in iter {
4765 if let SampleAttrs::Probability(val) = attr? {
4766 return Ok(val);
4767 }
4768 }
4769 Err(ErrorContext::new_missing(
4770 "SampleAttrs",
4771 "Probability",
4772 self.orig_loc,
4773 self.buf.as_ptr() as usize,
4774 ))
4775 }
4776 pub fn get_actions(&self) -> Result<IterableActionAttrs<'a>, ErrorContext> {
4777 let mut iter = self.clone();
4778 iter.pos = 0;
4779 for attr in iter {
4780 if let SampleAttrs::Actions(val) = attr? {
4781 return Ok(val);
4782 }
4783 }
4784 Err(ErrorContext::new_missing(
4785 "SampleAttrs",
4786 "Actions",
4787 self.orig_loc,
4788 self.buf.as_ptr() as usize,
4789 ))
4790 }
4791}
4792impl SampleAttrs<'_> {
4793 pub fn new<'a>(buf: &'a [u8]) -> IterableSampleAttrs<'a> {
4794 IterableSampleAttrs::with_loc(buf, buf.as_ptr() as usize)
4795 }
4796 fn attr_from_type(r#type: u16) -> Option<&'static str> {
4797 let res = match r#type {
4798 1u16 => "Probability",
4799 2u16 => "Actions",
4800 _ => return None,
4801 };
4802 Some(res)
4803 }
4804}
4805#[derive(Clone, Copy, Default)]
4806pub struct IterableSampleAttrs<'a> {
4807 buf: &'a [u8],
4808 pos: usize,
4809 orig_loc: usize,
4810}
4811impl<'a> IterableSampleAttrs<'a> {
4812 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
4813 Self {
4814 buf,
4815 pos: 0,
4816 orig_loc,
4817 }
4818 }
4819 pub fn get_buf(&self) -> &'a [u8] {
4820 self.buf
4821 }
4822}
4823impl<'a> Iterator for IterableSampleAttrs<'a> {
4824 type Item = Result<SampleAttrs<'a>, ErrorContext>;
4825 fn next(&mut self) -> Option<Self::Item> {
4826 let pos = self.pos;
4827 let mut r#type;
4828 loop {
4829 r#type = None;
4830 if self.buf.len() == self.pos {
4831 return None;
4832 }
4833 let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
4834 break;
4835 };
4836 r#type = Some(header.r#type);
4837 let res = match header.r#type {
4838 1u16 => SampleAttrs::Probability({
4839 let res = parse_u32(next);
4840 let Some(val) = res else { break };
4841 val
4842 }),
4843 2u16 => SampleAttrs::Actions({
4844 let res = Some(IterableActionAttrs::with_loc(next, self.orig_loc));
4845 let Some(val) = res else { break };
4846 val
4847 }),
4848 n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
4849 n => continue,
4850 };
4851 return Some(Ok(res));
4852 }
4853 Some(Err(ErrorContext::new(
4854 "SampleAttrs",
4855 r#type.and_then(|t| SampleAttrs::attr_from_type(t)),
4856 self.orig_loc,
4857 self.buf.as_ptr().wrapping_add(pos) as usize,
4858 )))
4859 }
4860}
4861impl<'a> std::fmt::Debug for IterableSampleAttrs<'_> {
4862 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
4863 let mut fmt = f.debug_struct("SampleAttrs");
4864 for attr in self.clone() {
4865 let attr = match attr {
4866 Ok(a) => a,
4867 Err(err) => {
4868 fmt.finish()?;
4869 f.write_str("Err(")?;
4870 err.fmt(f)?;
4871 return f.write_str(")");
4872 }
4873 };
4874 match attr {
4875 SampleAttrs::Probability(val) => fmt.field("Probability", &val),
4876 SampleAttrs::Actions(val) => fmt.field("Actions", &val),
4877 };
4878 }
4879 fmt.finish()
4880 }
4881}
4882impl IterableSampleAttrs<'_> {
4883 pub fn lookup_attr(
4884 &self,
4885 offset: usize,
4886 missing_type: Option<u16>,
4887 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
4888 let mut stack = Vec::new();
4889 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
4890 if missing_type.is_some() && cur == offset {
4891 stack.push(("SampleAttrs", offset));
4892 return (
4893 stack,
4894 missing_type.and_then(|t| SampleAttrs::attr_from_type(t)),
4895 );
4896 }
4897 if cur > offset || cur + self.buf.len() < offset {
4898 return (stack, None);
4899 }
4900 let mut attrs = self.clone();
4901 let mut last_off = cur + attrs.pos;
4902 let mut missing = None;
4903 while let Some(attr) = attrs.next() {
4904 let Ok(attr) = attr else { break };
4905 match attr {
4906 SampleAttrs::Probability(val) => {
4907 if last_off == offset {
4908 stack.push(("Probability", last_off));
4909 break;
4910 }
4911 }
4912 SampleAttrs::Actions(val) => {
4913 (stack, missing) = val.lookup_attr(offset, missing_type);
4914 if !stack.is_empty() {
4915 break;
4916 }
4917 }
4918 _ => {}
4919 };
4920 last_off = cur + attrs.pos;
4921 }
4922 if !stack.is_empty() {
4923 stack.push(("SampleAttrs", cur));
4924 }
4925 (stack, missing)
4926 }
4927}
4928#[derive(Clone)]
4929pub enum UserspaceAttrs<'a> {
4930 Pid(u32),
4931 Userdata(&'a [u8]),
4932 EgressTunPort(u32),
4933 Actions(()),
4934}
4935impl<'a> IterableUserspaceAttrs<'a> {
4936 pub fn get_pid(&self) -> Result<u32, ErrorContext> {
4937 let mut iter = self.clone();
4938 iter.pos = 0;
4939 for attr in iter {
4940 if let UserspaceAttrs::Pid(val) = attr? {
4941 return Ok(val);
4942 }
4943 }
4944 Err(ErrorContext::new_missing(
4945 "UserspaceAttrs",
4946 "Pid",
4947 self.orig_loc,
4948 self.buf.as_ptr() as usize,
4949 ))
4950 }
4951 pub fn get_userdata(&self) -> Result<&'a [u8], ErrorContext> {
4952 let mut iter = self.clone();
4953 iter.pos = 0;
4954 for attr in iter {
4955 if let UserspaceAttrs::Userdata(val) = attr? {
4956 return Ok(val);
4957 }
4958 }
4959 Err(ErrorContext::new_missing(
4960 "UserspaceAttrs",
4961 "Userdata",
4962 self.orig_loc,
4963 self.buf.as_ptr() as usize,
4964 ))
4965 }
4966 pub fn get_egress_tun_port(&self) -> Result<u32, ErrorContext> {
4967 let mut iter = self.clone();
4968 iter.pos = 0;
4969 for attr in iter {
4970 if let UserspaceAttrs::EgressTunPort(val) = attr? {
4971 return Ok(val);
4972 }
4973 }
4974 Err(ErrorContext::new_missing(
4975 "UserspaceAttrs",
4976 "EgressTunPort",
4977 self.orig_loc,
4978 self.buf.as_ptr() as usize,
4979 ))
4980 }
4981 pub fn get_actions(&self) -> Result<(), ErrorContext> {
4982 let mut iter = self.clone();
4983 iter.pos = 0;
4984 for attr in iter {
4985 if let UserspaceAttrs::Actions(val) = attr? {
4986 return Ok(val);
4987 }
4988 }
4989 Err(ErrorContext::new_missing(
4990 "UserspaceAttrs",
4991 "Actions",
4992 self.orig_loc,
4993 self.buf.as_ptr() as usize,
4994 ))
4995 }
4996}
4997impl UserspaceAttrs<'_> {
4998 pub fn new<'a>(buf: &'a [u8]) -> IterableUserspaceAttrs<'a> {
4999 IterableUserspaceAttrs::with_loc(buf, buf.as_ptr() as usize)
5000 }
5001 fn attr_from_type(r#type: u16) -> Option<&'static str> {
5002 let res = match r#type {
5003 1u16 => "Pid",
5004 2u16 => "Userdata",
5005 3u16 => "EgressTunPort",
5006 4u16 => "Actions",
5007 _ => return None,
5008 };
5009 Some(res)
5010 }
5011}
5012#[derive(Clone, Copy, Default)]
5013pub struct IterableUserspaceAttrs<'a> {
5014 buf: &'a [u8],
5015 pos: usize,
5016 orig_loc: usize,
5017}
5018impl<'a> IterableUserspaceAttrs<'a> {
5019 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
5020 Self {
5021 buf,
5022 pos: 0,
5023 orig_loc,
5024 }
5025 }
5026 pub fn get_buf(&self) -> &'a [u8] {
5027 self.buf
5028 }
5029}
5030impl<'a> Iterator for IterableUserspaceAttrs<'a> {
5031 type Item = Result<UserspaceAttrs<'a>, ErrorContext>;
5032 fn next(&mut self) -> Option<Self::Item> {
5033 let pos = self.pos;
5034 let mut r#type;
5035 loop {
5036 r#type = None;
5037 if self.buf.len() == self.pos {
5038 return None;
5039 }
5040 let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
5041 break;
5042 };
5043 r#type = Some(header.r#type);
5044 let res = match header.r#type {
5045 1u16 => UserspaceAttrs::Pid({
5046 let res = parse_u32(next);
5047 let Some(val) = res else { break };
5048 val
5049 }),
5050 2u16 => UserspaceAttrs::Userdata({
5051 let res = Some(next);
5052 let Some(val) = res else { break };
5053 val
5054 }),
5055 3u16 => UserspaceAttrs::EgressTunPort({
5056 let res = parse_u32(next);
5057 let Some(val) = res else { break };
5058 val
5059 }),
5060 4u16 => UserspaceAttrs::Actions(()),
5061 n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
5062 n => continue,
5063 };
5064 return Some(Ok(res));
5065 }
5066 Some(Err(ErrorContext::new(
5067 "UserspaceAttrs",
5068 r#type.and_then(|t| UserspaceAttrs::attr_from_type(t)),
5069 self.orig_loc,
5070 self.buf.as_ptr().wrapping_add(pos) as usize,
5071 )))
5072 }
5073}
5074impl<'a> std::fmt::Debug for IterableUserspaceAttrs<'_> {
5075 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
5076 let mut fmt = f.debug_struct("UserspaceAttrs");
5077 for attr in self.clone() {
5078 let attr = match attr {
5079 Ok(a) => a,
5080 Err(err) => {
5081 fmt.finish()?;
5082 f.write_str("Err(")?;
5083 err.fmt(f)?;
5084 return f.write_str(")");
5085 }
5086 };
5087 match attr {
5088 UserspaceAttrs::Pid(val) => fmt.field("Pid", &val),
5089 UserspaceAttrs::Userdata(val) => fmt.field("Userdata", &val),
5090 UserspaceAttrs::EgressTunPort(val) => fmt.field("EgressTunPort", &val),
5091 UserspaceAttrs::Actions(val) => fmt.field("Actions", &val),
5092 };
5093 }
5094 fmt.finish()
5095 }
5096}
5097impl IterableUserspaceAttrs<'_> {
5098 pub fn lookup_attr(
5099 &self,
5100 offset: usize,
5101 missing_type: Option<u16>,
5102 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
5103 let mut stack = Vec::new();
5104 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
5105 if missing_type.is_some() && cur == offset {
5106 stack.push(("UserspaceAttrs", offset));
5107 return (
5108 stack,
5109 missing_type.and_then(|t| UserspaceAttrs::attr_from_type(t)),
5110 );
5111 }
5112 if cur > offset || cur + self.buf.len() < offset {
5113 return (stack, None);
5114 }
5115 let mut attrs = self.clone();
5116 let mut last_off = cur + attrs.pos;
5117 while let Some(attr) = attrs.next() {
5118 let Ok(attr) = attr else { break };
5119 match attr {
5120 UserspaceAttrs::Pid(val) => {
5121 if last_off == offset {
5122 stack.push(("Pid", last_off));
5123 break;
5124 }
5125 }
5126 UserspaceAttrs::Userdata(val) => {
5127 if last_off == offset {
5128 stack.push(("Userdata", last_off));
5129 break;
5130 }
5131 }
5132 UserspaceAttrs::EgressTunPort(val) => {
5133 if last_off == offset {
5134 stack.push(("EgressTunPort", last_off));
5135 break;
5136 }
5137 }
5138 UserspaceAttrs::Actions(val) => {
5139 if last_off == offset {
5140 stack.push(("Actions", last_off));
5141 break;
5142 }
5143 }
5144 _ => {}
5145 };
5146 last_off = cur + attrs.pos;
5147 }
5148 if !stack.is_empty() {
5149 stack.push(("UserspaceAttrs", cur));
5150 }
5151 (stack, None)
5152 }
5153}
5154#[derive(Clone)]
5155pub enum OvsNshKeyAttrs<'a> {
5156 Base(&'a [u8]),
5157 Md1(&'a [u8]),
5158 Md2(&'a [u8]),
5159}
5160impl<'a> IterableOvsNshKeyAttrs<'a> {
5161 pub fn get_base(&self) -> Result<&'a [u8], ErrorContext> {
5162 let mut iter = self.clone();
5163 iter.pos = 0;
5164 for attr in iter {
5165 if let OvsNshKeyAttrs::Base(val) = attr? {
5166 return Ok(val);
5167 }
5168 }
5169 Err(ErrorContext::new_missing(
5170 "OvsNshKeyAttrs",
5171 "Base",
5172 self.orig_loc,
5173 self.buf.as_ptr() as usize,
5174 ))
5175 }
5176 pub fn get_md1(&self) -> Result<&'a [u8], ErrorContext> {
5177 let mut iter = self.clone();
5178 iter.pos = 0;
5179 for attr in iter {
5180 if let OvsNshKeyAttrs::Md1(val) = attr? {
5181 return Ok(val);
5182 }
5183 }
5184 Err(ErrorContext::new_missing(
5185 "OvsNshKeyAttrs",
5186 "Md1",
5187 self.orig_loc,
5188 self.buf.as_ptr() as usize,
5189 ))
5190 }
5191 pub fn get_md2(&self) -> Result<&'a [u8], ErrorContext> {
5192 let mut iter = self.clone();
5193 iter.pos = 0;
5194 for attr in iter {
5195 if let OvsNshKeyAttrs::Md2(val) = attr? {
5196 return Ok(val);
5197 }
5198 }
5199 Err(ErrorContext::new_missing(
5200 "OvsNshKeyAttrs",
5201 "Md2",
5202 self.orig_loc,
5203 self.buf.as_ptr() as usize,
5204 ))
5205 }
5206}
5207impl OvsNshKeyAttrs<'_> {
5208 pub fn new<'a>(buf: &'a [u8]) -> IterableOvsNshKeyAttrs<'a> {
5209 IterableOvsNshKeyAttrs::with_loc(buf, buf.as_ptr() as usize)
5210 }
5211 fn attr_from_type(r#type: u16) -> Option<&'static str> {
5212 let res = match r#type {
5213 1u16 => "Base",
5214 2u16 => "Md1",
5215 3u16 => "Md2",
5216 _ => return None,
5217 };
5218 Some(res)
5219 }
5220}
5221#[derive(Clone, Copy, Default)]
5222pub struct IterableOvsNshKeyAttrs<'a> {
5223 buf: &'a [u8],
5224 pos: usize,
5225 orig_loc: usize,
5226}
5227impl<'a> IterableOvsNshKeyAttrs<'a> {
5228 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
5229 Self {
5230 buf,
5231 pos: 0,
5232 orig_loc,
5233 }
5234 }
5235 pub fn get_buf(&self) -> &'a [u8] {
5236 self.buf
5237 }
5238}
5239impl<'a> Iterator for IterableOvsNshKeyAttrs<'a> {
5240 type Item = Result<OvsNshKeyAttrs<'a>, ErrorContext>;
5241 fn next(&mut self) -> Option<Self::Item> {
5242 let pos = self.pos;
5243 let mut r#type;
5244 loop {
5245 r#type = None;
5246 if self.buf.len() == self.pos {
5247 return None;
5248 }
5249 let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
5250 break;
5251 };
5252 r#type = Some(header.r#type);
5253 let res = match header.r#type {
5254 1u16 => OvsNshKeyAttrs::Base({
5255 let res = Some(next);
5256 let Some(val) = res else { break };
5257 val
5258 }),
5259 2u16 => OvsNshKeyAttrs::Md1({
5260 let res = Some(next);
5261 let Some(val) = res else { break };
5262 val
5263 }),
5264 3u16 => OvsNshKeyAttrs::Md2({
5265 let res = Some(next);
5266 let Some(val) = res else { break };
5267 val
5268 }),
5269 n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
5270 n => continue,
5271 };
5272 return Some(Ok(res));
5273 }
5274 Some(Err(ErrorContext::new(
5275 "OvsNshKeyAttrs",
5276 r#type.and_then(|t| OvsNshKeyAttrs::attr_from_type(t)),
5277 self.orig_loc,
5278 self.buf.as_ptr().wrapping_add(pos) as usize,
5279 )))
5280 }
5281}
5282impl<'a> std::fmt::Debug for IterableOvsNshKeyAttrs<'_> {
5283 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
5284 let mut fmt = f.debug_struct("OvsNshKeyAttrs");
5285 for attr in self.clone() {
5286 let attr = match attr {
5287 Ok(a) => a,
5288 Err(err) => {
5289 fmt.finish()?;
5290 f.write_str("Err(")?;
5291 err.fmt(f)?;
5292 return f.write_str(")");
5293 }
5294 };
5295 match attr {
5296 OvsNshKeyAttrs::Base(val) => fmt.field("Base", &val),
5297 OvsNshKeyAttrs::Md1(val) => fmt.field("Md1", &val),
5298 OvsNshKeyAttrs::Md2(val) => fmt.field("Md2", &val),
5299 };
5300 }
5301 fmt.finish()
5302 }
5303}
5304impl IterableOvsNshKeyAttrs<'_> {
5305 pub fn lookup_attr(
5306 &self,
5307 offset: usize,
5308 missing_type: Option<u16>,
5309 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
5310 let mut stack = Vec::new();
5311 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
5312 if missing_type.is_some() && cur == offset {
5313 stack.push(("OvsNshKeyAttrs", offset));
5314 return (
5315 stack,
5316 missing_type.and_then(|t| OvsNshKeyAttrs::attr_from_type(t)),
5317 );
5318 }
5319 if cur > offset || cur + self.buf.len() < offset {
5320 return (stack, None);
5321 }
5322 let mut attrs = self.clone();
5323 let mut last_off = cur + attrs.pos;
5324 while let Some(attr) = attrs.next() {
5325 let Ok(attr) = attr else { break };
5326 match attr {
5327 OvsNshKeyAttrs::Base(val) => {
5328 if last_off == offset {
5329 stack.push(("Base", last_off));
5330 break;
5331 }
5332 }
5333 OvsNshKeyAttrs::Md1(val) => {
5334 if last_off == offset {
5335 stack.push(("Md1", last_off));
5336 break;
5337 }
5338 }
5339 OvsNshKeyAttrs::Md2(val) => {
5340 if last_off == offset {
5341 stack.push(("Md2", last_off));
5342 break;
5343 }
5344 }
5345 _ => {}
5346 };
5347 last_off = cur + attrs.pos;
5348 }
5349 if !stack.is_empty() {
5350 stack.push(("OvsNshKeyAttrs", cur));
5351 }
5352 (stack, None)
5353 }
5354}
5355#[derive(Clone)]
5356pub enum CtAttrs<'a> {
5357 Commit(()),
5358 Zone(u16),
5359 Mark(&'a [u8]),
5360 Labels(&'a [u8]),
5361 Helper(&'a CStr),
5362 Nat(IterableNatAttrs<'a>),
5363 ForceCommit(()),
5364 Eventmask(u32),
5365 Timeout(&'a CStr),
5366}
5367impl<'a> IterableCtAttrs<'a> {
5368 pub fn get_commit(&self) -> Result<(), ErrorContext> {
5369 let mut iter = self.clone();
5370 iter.pos = 0;
5371 for attr in iter {
5372 if let CtAttrs::Commit(val) = attr? {
5373 return Ok(val);
5374 }
5375 }
5376 Err(ErrorContext::new_missing(
5377 "CtAttrs",
5378 "Commit",
5379 self.orig_loc,
5380 self.buf.as_ptr() as usize,
5381 ))
5382 }
5383 pub fn get_zone(&self) -> Result<u16, ErrorContext> {
5384 let mut iter = self.clone();
5385 iter.pos = 0;
5386 for attr in iter {
5387 if let CtAttrs::Zone(val) = attr? {
5388 return Ok(val);
5389 }
5390 }
5391 Err(ErrorContext::new_missing(
5392 "CtAttrs",
5393 "Zone",
5394 self.orig_loc,
5395 self.buf.as_ptr() as usize,
5396 ))
5397 }
5398 pub fn get_mark(&self) -> Result<&'a [u8], ErrorContext> {
5399 let mut iter = self.clone();
5400 iter.pos = 0;
5401 for attr in iter {
5402 if let CtAttrs::Mark(val) = attr? {
5403 return Ok(val);
5404 }
5405 }
5406 Err(ErrorContext::new_missing(
5407 "CtAttrs",
5408 "Mark",
5409 self.orig_loc,
5410 self.buf.as_ptr() as usize,
5411 ))
5412 }
5413 pub fn get_labels(&self) -> Result<&'a [u8], ErrorContext> {
5414 let mut iter = self.clone();
5415 iter.pos = 0;
5416 for attr in iter {
5417 if let CtAttrs::Labels(val) = attr? {
5418 return Ok(val);
5419 }
5420 }
5421 Err(ErrorContext::new_missing(
5422 "CtAttrs",
5423 "Labels",
5424 self.orig_loc,
5425 self.buf.as_ptr() as usize,
5426 ))
5427 }
5428 pub fn get_helper(&self) -> Result<&'a CStr, ErrorContext> {
5429 let mut iter = self.clone();
5430 iter.pos = 0;
5431 for attr in iter {
5432 if let CtAttrs::Helper(val) = attr? {
5433 return Ok(val);
5434 }
5435 }
5436 Err(ErrorContext::new_missing(
5437 "CtAttrs",
5438 "Helper",
5439 self.orig_loc,
5440 self.buf.as_ptr() as usize,
5441 ))
5442 }
5443 pub fn get_nat(&self) -> Result<IterableNatAttrs<'a>, ErrorContext> {
5444 let mut iter = self.clone();
5445 iter.pos = 0;
5446 for attr in iter {
5447 if let CtAttrs::Nat(val) = attr? {
5448 return Ok(val);
5449 }
5450 }
5451 Err(ErrorContext::new_missing(
5452 "CtAttrs",
5453 "Nat",
5454 self.orig_loc,
5455 self.buf.as_ptr() as usize,
5456 ))
5457 }
5458 pub fn get_force_commit(&self) -> Result<(), ErrorContext> {
5459 let mut iter = self.clone();
5460 iter.pos = 0;
5461 for attr in iter {
5462 if let CtAttrs::ForceCommit(val) = attr? {
5463 return Ok(val);
5464 }
5465 }
5466 Err(ErrorContext::new_missing(
5467 "CtAttrs",
5468 "ForceCommit",
5469 self.orig_loc,
5470 self.buf.as_ptr() as usize,
5471 ))
5472 }
5473 pub fn get_eventmask(&self) -> Result<u32, ErrorContext> {
5474 let mut iter = self.clone();
5475 iter.pos = 0;
5476 for attr in iter {
5477 if let CtAttrs::Eventmask(val) = attr? {
5478 return Ok(val);
5479 }
5480 }
5481 Err(ErrorContext::new_missing(
5482 "CtAttrs",
5483 "Eventmask",
5484 self.orig_loc,
5485 self.buf.as_ptr() as usize,
5486 ))
5487 }
5488 pub fn get_timeout(&self) -> Result<&'a CStr, ErrorContext> {
5489 let mut iter = self.clone();
5490 iter.pos = 0;
5491 for attr in iter {
5492 if let CtAttrs::Timeout(val) = attr? {
5493 return Ok(val);
5494 }
5495 }
5496 Err(ErrorContext::new_missing(
5497 "CtAttrs",
5498 "Timeout",
5499 self.orig_loc,
5500 self.buf.as_ptr() as usize,
5501 ))
5502 }
5503}
5504impl CtAttrs<'_> {
5505 pub fn new<'a>(buf: &'a [u8]) -> IterableCtAttrs<'a> {
5506 IterableCtAttrs::with_loc(buf, buf.as_ptr() as usize)
5507 }
5508 fn attr_from_type(r#type: u16) -> Option<&'static str> {
5509 let res = match r#type {
5510 1u16 => "Commit",
5511 2u16 => "Zone",
5512 3u16 => "Mark",
5513 4u16 => "Labels",
5514 5u16 => "Helper",
5515 6u16 => "Nat",
5516 7u16 => "ForceCommit",
5517 8u16 => "Eventmask",
5518 9u16 => "Timeout",
5519 _ => return None,
5520 };
5521 Some(res)
5522 }
5523}
5524#[derive(Clone, Copy, Default)]
5525pub struct IterableCtAttrs<'a> {
5526 buf: &'a [u8],
5527 pos: usize,
5528 orig_loc: usize,
5529}
5530impl<'a> IterableCtAttrs<'a> {
5531 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
5532 Self {
5533 buf,
5534 pos: 0,
5535 orig_loc,
5536 }
5537 }
5538 pub fn get_buf(&self) -> &'a [u8] {
5539 self.buf
5540 }
5541}
5542impl<'a> Iterator for IterableCtAttrs<'a> {
5543 type Item = Result<CtAttrs<'a>, ErrorContext>;
5544 fn next(&mut self) -> Option<Self::Item> {
5545 let pos = self.pos;
5546 let mut r#type;
5547 loop {
5548 r#type = None;
5549 if self.buf.len() == self.pos {
5550 return None;
5551 }
5552 let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
5553 break;
5554 };
5555 r#type = Some(header.r#type);
5556 let res = match header.r#type {
5557 1u16 => CtAttrs::Commit(()),
5558 2u16 => CtAttrs::Zone({
5559 let res = parse_u16(next);
5560 let Some(val) = res else { break };
5561 val
5562 }),
5563 3u16 => CtAttrs::Mark({
5564 let res = Some(next);
5565 let Some(val) = res else { break };
5566 val
5567 }),
5568 4u16 => CtAttrs::Labels({
5569 let res = Some(next);
5570 let Some(val) = res else { break };
5571 val
5572 }),
5573 5u16 => CtAttrs::Helper({
5574 let res = CStr::from_bytes_with_nul(next).ok();
5575 let Some(val) = res else { break };
5576 val
5577 }),
5578 6u16 => CtAttrs::Nat({
5579 let res = Some(IterableNatAttrs::with_loc(next, self.orig_loc));
5580 let Some(val) = res else { break };
5581 val
5582 }),
5583 7u16 => CtAttrs::ForceCommit(()),
5584 8u16 => CtAttrs::Eventmask({
5585 let res = parse_u32(next);
5586 let Some(val) = res else { break };
5587 val
5588 }),
5589 9u16 => CtAttrs::Timeout({
5590 let res = CStr::from_bytes_with_nul(next).ok();
5591 let Some(val) = res else { break };
5592 val
5593 }),
5594 n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
5595 n => continue,
5596 };
5597 return Some(Ok(res));
5598 }
5599 Some(Err(ErrorContext::new(
5600 "CtAttrs",
5601 r#type.and_then(|t| CtAttrs::attr_from_type(t)),
5602 self.orig_loc,
5603 self.buf.as_ptr().wrapping_add(pos) as usize,
5604 )))
5605 }
5606}
5607impl<'a> std::fmt::Debug for IterableCtAttrs<'_> {
5608 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
5609 let mut fmt = f.debug_struct("CtAttrs");
5610 for attr in self.clone() {
5611 let attr = match attr {
5612 Ok(a) => a,
5613 Err(err) => {
5614 fmt.finish()?;
5615 f.write_str("Err(")?;
5616 err.fmt(f)?;
5617 return f.write_str(")");
5618 }
5619 };
5620 match attr {
5621 CtAttrs::Commit(val) => fmt.field("Commit", &val),
5622 CtAttrs::Zone(val) => fmt.field("Zone", &val),
5623 CtAttrs::Mark(val) => fmt.field("Mark", &val),
5624 CtAttrs::Labels(val) => fmt.field("Labels", &val),
5625 CtAttrs::Helper(val) => fmt.field("Helper", &val),
5626 CtAttrs::Nat(val) => fmt.field("Nat", &val),
5627 CtAttrs::ForceCommit(val) => fmt.field("ForceCommit", &val),
5628 CtAttrs::Eventmask(val) => fmt.field("Eventmask", &val),
5629 CtAttrs::Timeout(val) => fmt.field("Timeout", &val),
5630 };
5631 }
5632 fmt.finish()
5633 }
5634}
5635impl IterableCtAttrs<'_> {
5636 pub fn lookup_attr(
5637 &self,
5638 offset: usize,
5639 missing_type: Option<u16>,
5640 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
5641 let mut stack = Vec::new();
5642 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
5643 if missing_type.is_some() && cur == offset {
5644 stack.push(("CtAttrs", offset));
5645 return (stack, missing_type.and_then(|t| CtAttrs::attr_from_type(t)));
5646 }
5647 if cur > offset || cur + self.buf.len() < offset {
5648 return (stack, None);
5649 }
5650 let mut attrs = self.clone();
5651 let mut last_off = cur + attrs.pos;
5652 let mut missing = None;
5653 while let Some(attr) = attrs.next() {
5654 let Ok(attr) = attr else { break };
5655 match attr {
5656 CtAttrs::Commit(val) => {
5657 if last_off == offset {
5658 stack.push(("Commit", last_off));
5659 break;
5660 }
5661 }
5662 CtAttrs::Zone(val) => {
5663 if last_off == offset {
5664 stack.push(("Zone", last_off));
5665 break;
5666 }
5667 }
5668 CtAttrs::Mark(val) => {
5669 if last_off == offset {
5670 stack.push(("Mark", last_off));
5671 break;
5672 }
5673 }
5674 CtAttrs::Labels(val) => {
5675 if last_off == offset {
5676 stack.push(("Labels", last_off));
5677 break;
5678 }
5679 }
5680 CtAttrs::Helper(val) => {
5681 if last_off == offset {
5682 stack.push(("Helper", last_off));
5683 break;
5684 }
5685 }
5686 CtAttrs::Nat(val) => {
5687 (stack, missing) = val.lookup_attr(offset, missing_type);
5688 if !stack.is_empty() {
5689 break;
5690 }
5691 }
5692 CtAttrs::ForceCommit(val) => {
5693 if last_off == offset {
5694 stack.push(("ForceCommit", last_off));
5695 break;
5696 }
5697 }
5698 CtAttrs::Eventmask(val) => {
5699 if last_off == offset {
5700 stack.push(("Eventmask", last_off));
5701 break;
5702 }
5703 }
5704 CtAttrs::Timeout(val) => {
5705 if last_off == offset {
5706 stack.push(("Timeout", last_off));
5707 break;
5708 }
5709 }
5710 _ => {}
5711 };
5712 last_off = cur + attrs.pos;
5713 }
5714 if !stack.is_empty() {
5715 stack.push(("CtAttrs", cur));
5716 }
5717 (stack, missing)
5718 }
5719}
5720#[derive(Clone)]
5721pub enum NatAttrs<'a> {
5722 Src(()),
5723 Dst(()),
5724 IpMin(&'a [u8]),
5725 IpMax(&'a [u8]),
5726 ProtoMin(u16),
5727 ProtoMax(u16),
5728 Persistent(()),
5729 ProtoHash(()),
5730 ProtoRandom(()),
5731}
5732impl<'a> IterableNatAttrs<'a> {
5733 pub fn get_src(&self) -> Result<(), ErrorContext> {
5734 let mut iter = self.clone();
5735 iter.pos = 0;
5736 for attr in iter {
5737 if let NatAttrs::Src(val) = attr? {
5738 return Ok(val);
5739 }
5740 }
5741 Err(ErrorContext::new_missing(
5742 "NatAttrs",
5743 "Src",
5744 self.orig_loc,
5745 self.buf.as_ptr() as usize,
5746 ))
5747 }
5748 pub fn get_dst(&self) -> Result<(), ErrorContext> {
5749 let mut iter = self.clone();
5750 iter.pos = 0;
5751 for attr in iter {
5752 if let NatAttrs::Dst(val) = attr? {
5753 return Ok(val);
5754 }
5755 }
5756 Err(ErrorContext::new_missing(
5757 "NatAttrs",
5758 "Dst",
5759 self.orig_loc,
5760 self.buf.as_ptr() as usize,
5761 ))
5762 }
5763 pub fn get_ip_min(&self) -> Result<&'a [u8], ErrorContext> {
5764 let mut iter = self.clone();
5765 iter.pos = 0;
5766 for attr in iter {
5767 if let NatAttrs::IpMin(val) = attr? {
5768 return Ok(val);
5769 }
5770 }
5771 Err(ErrorContext::new_missing(
5772 "NatAttrs",
5773 "IpMin",
5774 self.orig_loc,
5775 self.buf.as_ptr() as usize,
5776 ))
5777 }
5778 pub fn get_ip_max(&self) -> Result<&'a [u8], ErrorContext> {
5779 let mut iter = self.clone();
5780 iter.pos = 0;
5781 for attr in iter {
5782 if let NatAttrs::IpMax(val) = attr? {
5783 return Ok(val);
5784 }
5785 }
5786 Err(ErrorContext::new_missing(
5787 "NatAttrs",
5788 "IpMax",
5789 self.orig_loc,
5790 self.buf.as_ptr() as usize,
5791 ))
5792 }
5793 pub fn get_proto_min(&self) -> Result<u16, ErrorContext> {
5794 let mut iter = self.clone();
5795 iter.pos = 0;
5796 for attr in iter {
5797 if let NatAttrs::ProtoMin(val) = attr? {
5798 return Ok(val);
5799 }
5800 }
5801 Err(ErrorContext::new_missing(
5802 "NatAttrs",
5803 "ProtoMin",
5804 self.orig_loc,
5805 self.buf.as_ptr() as usize,
5806 ))
5807 }
5808 pub fn get_proto_max(&self) -> Result<u16, ErrorContext> {
5809 let mut iter = self.clone();
5810 iter.pos = 0;
5811 for attr in iter {
5812 if let NatAttrs::ProtoMax(val) = attr? {
5813 return Ok(val);
5814 }
5815 }
5816 Err(ErrorContext::new_missing(
5817 "NatAttrs",
5818 "ProtoMax",
5819 self.orig_loc,
5820 self.buf.as_ptr() as usize,
5821 ))
5822 }
5823 pub fn get_persistent(&self) -> Result<(), ErrorContext> {
5824 let mut iter = self.clone();
5825 iter.pos = 0;
5826 for attr in iter {
5827 if let NatAttrs::Persistent(val) = attr? {
5828 return Ok(val);
5829 }
5830 }
5831 Err(ErrorContext::new_missing(
5832 "NatAttrs",
5833 "Persistent",
5834 self.orig_loc,
5835 self.buf.as_ptr() as usize,
5836 ))
5837 }
5838 pub fn get_proto_hash(&self) -> Result<(), ErrorContext> {
5839 let mut iter = self.clone();
5840 iter.pos = 0;
5841 for attr in iter {
5842 if let NatAttrs::ProtoHash(val) = attr? {
5843 return Ok(val);
5844 }
5845 }
5846 Err(ErrorContext::new_missing(
5847 "NatAttrs",
5848 "ProtoHash",
5849 self.orig_loc,
5850 self.buf.as_ptr() as usize,
5851 ))
5852 }
5853 pub fn get_proto_random(&self) -> Result<(), ErrorContext> {
5854 let mut iter = self.clone();
5855 iter.pos = 0;
5856 for attr in iter {
5857 if let NatAttrs::ProtoRandom(val) = attr? {
5858 return Ok(val);
5859 }
5860 }
5861 Err(ErrorContext::new_missing(
5862 "NatAttrs",
5863 "ProtoRandom",
5864 self.orig_loc,
5865 self.buf.as_ptr() as usize,
5866 ))
5867 }
5868}
5869impl NatAttrs<'_> {
5870 pub fn new<'a>(buf: &'a [u8]) -> IterableNatAttrs<'a> {
5871 IterableNatAttrs::with_loc(buf, buf.as_ptr() as usize)
5872 }
5873 fn attr_from_type(r#type: u16) -> Option<&'static str> {
5874 let res = match r#type {
5875 1u16 => "Src",
5876 2u16 => "Dst",
5877 3u16 => "IpMin",
5878 4u16 => "IpMax",
5879 5u16 => "ProtoMin",
5880 6u16 => "ProtoMax",
5881 7u16 => "Persistent",
5882 8u16 => "ProtoHash",
5883 9u16 => "ProtoRandom",
5884 _ => return None,
5885 };
5886 Some(res)
5887 }
5888}
5889#[derive(Clone, Copy, Default)]
5890pub struct IterableNatAttrs<'a> {
5891 buf: &'a [u8],
5892 pos: usize,
5893 orig_loc: usize,
5894}
5895impl<'a> IterableNatAttrs<'a> {
5896 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
5897 Self {
5898 buf,
5899 pos: 0,
5900 orig_loc,
5901 }
5902 }
5903 pub fn get_buf(&self) -> &'a [u8] {
5904 self.buf
5905 }
5906}
5907impl<'a> Iterator for IterableNatAttrs<'a> {
5908 type Item = Result<NatAttrs<'a>, ErrorContext>;
5909 fn next(&mut self) -> Option<Self::Item> {
5910 let pos = self.pos;
5911 let mut r#type;
5912 loop {
5913 r#type = None;
5914 if self.buf.len() == self.pos {
5915 return None;
5916 }
5917 let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
5918 break;
5919 };
5920 r#type = Some(header.r#type);
5921 let res = match header.r#type {
5922 1u16 => NatAttrs::Src(()),
5923 2u16 => NatAttrs::Dst(()),
5924 3u16 => NatAttrs::IpMin({
5925 let res = Some(next);
5926 let Some(val) = res else { break };
5927 val
5928 }),
5929 4u16 => NatAttrs::IpMax({
5930 let res = Some(next);
5931 let Some(val) = res else { break };
5932 val
5933 }),
5934 5u16 => NatAttrs::ProtoMin({
5935 let res = parse_u16(next);
5936 let Some(val) = res else { break };
5937 val
5938 }),
5939 6u16 => NatAttrs::ProtoMax({
5940 let res = parse_u16(next);
5941 let Some(val) = res else { break };
5942 val
5943 }),
5944 7u16 => NatAttrs::Persistent(()),
5945 8u16 => NatAttrs::ProtoHash(()),
5946 9u16 => NatAttrs::ProtoRandom(()),
5947 n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
5948 n => continue,
5949 };
5950 return Some(Ok(res));
5951 }
5952 Some(Err(ErrorContext::new(
5953 "NatAttrs",
5954 r#type.and_then(|t| NatAttrs::attr_from_type(t)),
5955 self.orig_loc,
5956 self.buf.as_ptr().wrapping_add(pos) as usize,
5957 )))
5958 }
5959}
5960impl<'a> std::fmt::Debug for IterableNatAttrs<'_> {
5961 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
5962 let mut fmt = f.debug_struct("NatAttrs");
5963 for attr in self.clone() {
5964 let attr = match attr {
5965 Ok(a) => a,
5966 Err(err) => {
5967 fmt.finish()?;
5968 f.write_str("Err(")?;
5969 err.fmt(f)?;
5970 return f.write_str(")");
5971 }
5972 };
5973 match attr {
5974 NatAttrs::Src(val) => fmt.field("Src", &val),
5975 NatAttrs::Dst(val) => fmt.field("Dst", &val),
5976 NatAttrs::IpMin(val) => fmt.field("IpMin", &val),
5977 NatAttrs::IpMax(val) => fmt.field("IpMax", &val),
5978 NatAttrs::ProtoMin(val) => fmt.field("ProtoMin", &val),
5979 NatAttrs::ProtoMax(val) => fmt.field("ProtoMax", &val),
5980 NatAttrs::Persistent(val) => fmt.field("Persistent", &val),
5981 NatAttrs::ProtoHash(val) => fmt.field("ProtoHash", &val),
5982 NatAttrs::ProtoRandom(val) => fmt.field("ProtoRandom", &val),
5983 };
5984 }
5985 fmt.finish()
5986 }
5987}
5988impl IterableNatAttrs<'_> {
5989 pub fn lookup_attr(
5990 &self,
5991 offset: usize,
5992 missing_type: Option<u16>,
5993 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
5994 let mut stack = Vec::new();
5995 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
5996 if missing_type.is_some() && cur == offset {
5997 stack.push(("NatAttrs", offset));
5998 return (
5999 stack,
6000 missing_type.and_then(|t| NatAttrs::attr_from_type(t)),
6001 );
6002 }
6003 if cur > offset || cur + self.buf.len() < offset {
6004 return (stack, None);
6005 }
6006 let mut attrs = self.clone();
6007 let mut last_off = cur + attrs.pos;
6008 while let Some(attr) = attrs.next() {
6009 let Ok(attr) = attr else { break };
6010 match attr {
6011 NatAttrs::Src(val) => {
6012 if last_off == offset {
6013 stack.push(("Src", last_off));
6014 break;
6015 }
6016 }
6017 NatAttrs::Dst(val) => {
6018 if last_off == offset {
6019 stack.push(("Dst", last_off));
6020 break;
6021 }
6022 }
6023 NatAttrs::IpMin(val) => {
6024 if last_off == offset {
6025 stack.push(("IpMin", last_off));
6026 break;
6027 }
6028 }
6029 NatAttrs::IpMax(val) => {
6030 if last_off == offset {
6031 stack.push(("IpMax", last_off));
6032 break;
6033 }
6034 }
6035 NatAttrs::ProtoMin(val) => {
6036 if last_off == offset {
6037 stack.push(("ProtoMin", last_off));
6038 break;
6039 }
6040 }
6041 NatAttrs::ProtoMax(val) => {
6042 if last_off == offset {
6043 stack.push(("ProtoMax", last_off));
6044 break;
6045 }
6046 }
6047 NatAttrs::Persistent(val) => {
6048 if last_off == offset {
6049 stack.push(("Persistent", last_off));
6050 break;
6051 }
6052 }
6053 NatAttrs::ProtoHash(val) => {
6054 if last_off == offset {
6055 stack.push(("ProtoHash", last_off));
6056 break;
6057 }
6058 }
6059 NatAttrs::ProtoRandom(val) => {
6060 if last_off == offset {
6061 stack.push(("ProtoRandom", last_off));
6062 break;
6063 }
6064 }
6065 _ => {}
6066 };
6067 last_off = cur + attrs.pos;
6068 }
6069 if !stack.is_empty() {
6070 stack.push(("NatAttrs", cur));
6071 }
6072 (stack, None)
6073 }
6074}
6075#[derive(Clone)]
6076pub enum DecTtlAttrs<'a> {
6077 Action(IterableActionAttrs<'a>),
6078}
6079impl<'a> IterableDecTtlAttrs<'a> {
6080 pub fn get_action(&self) -> Result<IterableActionAttrs<'a>, ErrorContext> {
6081 let mut iter = self.clone();
6082 iter.pos = 0;
6083 for attr in iter {
6084 if let DecTtlAttrs::Action(val) = attr? {
6085 return Ok(val);
6086 }
6087 }
6088 Err(ErrorContext::new_missing(
6089 "DecTtlAttrs",
6090 "Action",
6091 self.orig_loc,
6092 self.buf.as_ptr() as usize,
6093 ))
6094 }
6095}
6096impl DecTtlAttrs<'_> {
6097 pub fn new<'a>(buf: &'a [u8]) -> IterableDecTtlAttrs<'a> {
6098 IterableDecTtlAttrs::with_loc(buf, buf.as_ptr() as usize)
6099 }
6100 fn attr_from_type(r#type: u16) -> Option<&'static str> {
6101 let res = match r#type {
6102 1u16 => "Action",
6103 _ => return None,
6104 };
6105 Some(res)
6106 }
6107}
6108#[derive(Clone, Copy, Default)]
6109pub struct IterableDecTtlAttrs<'a> {
6110 buf: &'a [u8],
6111 pos: usize,
6112 orig_loc: usize,
6113}
6114impl<'a> IterableDecTtlAttrs<'a> {
6115 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
6116 Self {
6117 buf,
6118 pos: 0,
6119 orig_loc,
6120 }
6121 }
6122 pub fn get_buf(&self) -> &'a [u8] {
6123 self.buf
6124 }
6125}
6126impl<'a> Iterator for IterableDecTtlAttrs<'a> {
6127 type Item = Result<DecTtlAttrs<'a>, ErrorContext>;
6128 fn next(&mut self) -> Option<Self::Item> {
6129 let pos = self.pos;
6130 let mut r#type;
6131 loop {
6132 r#type = None;
6133 if self.buf.len() == self.pos {
6134 return None;
6135 }
6136 let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
6137 break;
6138 };
6139 r#type = Some(header.r#type);
6140 let res = match header.r#type {
6141 1u16 => DecTtlAttrs::Action({
6142 let res = Some(IterableActionAttrs::with_loc(next, self.orig_loc));
6143 let Some(val) = res else { break };
6144 val
6145 }),
6146 n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
6147 n => continue,
6148 };
6149 return Some(Ok(res));
6150 }
6151 Some(Err(ErrorContext::new(
6152 "DecTtlAttrs",
6153 r#type.and_then(|t| DecTtlAttrs::attr_from_type(t)),
6154 self.orig_loc,
6155 self.buf.as_ptr().wrapping_add(pos) as usize,
6156 )))
6157 }
6158}
6159impl<'a> std::fmt::Debug for IterableDecTtlAttrs<'_> {
6160 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
6161 let mut fmt = f.debug_struct("DecTtlAttrs");
6162 for attr in self.clone() {
6163 let attr = match attr {
6164 Ok(a) => a,
6165 Err(err) => {
6166 fmt.finish()?;
6167 f.write_str("Err(")?;
6168 err.fmt(f)?;
6169 return f.write_str(")");
6170 }
6171 };
6172 match attr {
6173 DecTtlAttrs::Action(val) => fmt.field("Action", &val),
6174 };
6175 }
6176 fmt.finish()
6177 }
6178}
6179impl IterableDecTtlAttrs<'_> {
6180 pub fn lookup_attr(
6181 &self,
6182 offset: usize,
6183 missing_type: Option<u16>,
6184 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
6185 let mut stack = Vec::new();
6186 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
6187 if missing_type.is_some() && cur == offset {
6188 stack.push(("DecTtlAttrs", offset));
6189 return (
6190 stack,
6191 missing_type.and_then(|t| DecTtlAttrs::attr_from_type(t)),
6192 );
6193 }
6194 if cur > offset || cur + self.buf.len() < offset {
6195 return (stack, None);
6196 }
6197 let mut attrs = self.clone();
6198 let mut last_off = cur + attrs.pos;
6199 let mut missing = None;
6200 while let Some(attr) = attrs.next() {
6201 let Ok(attr) = attr else { break };
6202 match attr {
6203 DecTtlAttrs::Action(val) => {
6204 (stack, missing) = val.lookup_attr(offset, missing_type);
6205 if !stack.is_empty() {
6206 break;
6207 }
6208 }
6209 _ => {}
6210 };
6211 last_off = cur + attrs.pos;
6212 }
6213 if !stack.is_empty() {
6214 stack.push(("DecTtlAttrs", cur));
6215 }
6216 (stack, missing)
6217 }
6218}
6219#[derive(Clone)]
6220pub enum VxlanExtAttrs {
6221 Gbp(u32),
6222}
6223impl<'a> IterableVxlanExtAttrs<'a> {
6224 pub fn get_gbp(&self) -> Result<u32, ErrorContext> {
6225 let mut iter = self.clone();
6226 iter.pos = 0;
6227 for attr in iter {
6228 if let VxlanExtAttrs::Gbp(val) = attr? {
6229 return Ok(val);
6230 }
6231 }
6232 Err(ErrorContext::new_missing(
6233 "VxlanExtAttrs",
6234 "Gbp",
6235 self.orig_loc,
6236 self.buf.as_ptr() as usize,
6237 ))
6238 }
6239}
6240impl VxlanExtAttrs {
6241 pub fn new<'a>(buf: &'a [u8]) -> IterableVxlanExtAttrs<'a> {
6242 IterableVxlanExtAttrs::with_loc(buf, buf.as_ptr() as usize)
6243 }
6244 fn attr_from_type(r#type: u16) -> Option<&'static str> {
6245 let res = match r#type {
6246 1u16 => "Gbp",
6247 _ => return None,
6248 };
6249 Some(res)
6250 }
6251}
6252#[derive(Clone, Copy, Default)]
6253pub struct IterableVxlanExtAttrs<'a> {
6254 buf: &'a [u8],
6255 pos: usize,
6256 orig_loc: usize,
6257}
6258impl<'a> IterableVxlanExtAttrs<'a> {
6259 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
6260 Self {
6261 buf,
6262 pos: 0,
6263 orig_loc,
6264 }
6265 }
6266 pub fn get_buf(&self) -> &'a [u8] {
6267 self.buf
6268 }
6269}
6270impl<'a> Iterator for IterableVxlanExtAttrs<'a> {
6271 type Item = Result<VxlanExtAttrs, ErrorContext>;
6272 fn next(&mut self) -> Option<Self::Item> {
6273 let pos = self.pos;
6274 let mut r#type;
6275 loop {
6276 r#type = None;
6277 if self.buf.len() == self.pos {
6278 return None;
6279 }
6280 let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
6281 break;
6282 };
6283 r#type = Some(header.r#type);
6284 let res = match header.r#type {
6285 1u16 => VxlanExtAttrs::Gbp({
6286 let res = parse_u32(next);
6287 let Some(val) = res else { break };
6288 val
6289 }),
6290 n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
6291 n => continue,
6292 };
6293 return Some(Ok(res));
6294 }
6295 Some(Err(ErrorContext::new(
6296 "VxlanExtAttrs",
6297 r#type.and_then(|t| VxlanExtAttrs::attr_from_type(t)),
6298 self.orig_loc,
6299 self.buf.as_ptr().wrapping_add(pos) as usize,
6300 )))
6301 }
6302}
6303impl std::fmt::Debug for IterableVxlanExtAttrs<'_> {
6304 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
6305 let mut fmt = f.debug_struct("VxlanExtAttrs");
6306 for attr in self.clone() {
6307 let attr = match attr {
6308 Ok(a) => a,
6309 Err(err) => {
6310 fmt.finish()?;
6311 f.write_str("Err(")?;
6312 err.fmt(f)?;
6313 return f.write_str(")");
6314 }
6315 };
6316 match attr {
6317 VxlanExtAttrs::Gbp(val) => fmt.field("Gbp", &val),
6318 };
6319 }
6320 fmt.finish()
6321 }
6322}
6323impl IterableVxlanExtAttrs<'_> {
6324 pub fn lookup_attr(
6325 &self,
6326 offset: usize,
6327 missing_type: Option<u16>,
6328 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
6329 let mut stack = Vec::new();
6330 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
6331 if missing_type.is_some() && cur == offset {
6332 stack.push(("VxlanExtAttrs", offset));
6333 return (
6334 stack,
6335 missing_type.and_then(|t| VxlanExtAttrs::attr_from_type(t)),
6336 );
6337 }
6338 if cur > offset || cur + self.buf.len() < offset {
6339 return (stack, None);
6340 }
6341 let mut attrs = self.clone();
6342 let mut last_off = cur + attrs.pos;
6343 while let Some(attr) = attrs.next() {
6344 let Ok(attr) = attr else { break };
6345 match attr {
6346 VxlanExtAttrs::Gbp(val) => {
6347 if last_off == offset {
6348 stack.push(("Gbp", last_off));
6349 break;
6350 }
6351 }
6352 _ => {}
6353 };
6354 last_off = cur + attrs.pos;
6355 }
6356 if !stack.is_empty() {
6357 stack.push(("VxlanExtAttrs", cur));
6358 }
6359 (stack, None)
6360 }
6361}
6362#[derive(Clone)]
6363pub enum PsampleAttrs<'a> {
6364 Group(u32),
6365 Cookie(&'a [u8]),
6366}
6367impl<'a> IterablePsampleAttrs<'a> {
6368 pub fn get_group(&self) -> Result<u32, ErrorContext> {
6369 let mut iter = self.clone();
6370 iter.pos = 0;
6371 for attr in iter {
6372 if let PsampleAttrs::Group(val) = attr? {
6373 return Ok(val);
6374 }
6375 }
6376 Err(ErrorContext::new_missing(
6377 "PsampleAttrs",
6378 "Group",
6379 self.orig_loc,
6380 self.buf.as_ptr() as usize,
6381 ))
6382 }
6383 pub fn get_cookie(&self) -> Result<&'a [u8], ErrorContext> {
6384 let mut iter = self.clone();
6385 iter.pos = 0;
6386 for attr in iter {
6387 if let PsampleAttrs::Cookie(val) = attr? {
6388 return Ok(val);
6389 }
6390 }
6391 Err(ErrorContext::new_missing(
6392 "PsampleAttrs",
6393 "Cookie",
6394 self.orig_loc,
6395 self.buf.as_ptr() as usize,
6396 ))
6397 }
6398}
6399impl PsampleAttrs<'_> {
6400 pub fn new<'a>(buf: &'a [u8]) -> IterablePsampleAttrs<'a> {
6401 IterablePsampleAttrs::with_loc(buf, buf.as_ptr() as usize)
6402 }
6403 fn attr_from_type(r#type: u16) -> Option<&'static str> {
6404 let res = match r#type {
6405 1u16 => "Group",
6406 2u16 => "Cookie",
6407 _ => return None,
6408 };
6409 Some(res)
6410 }
6411}
6412#[derive(Clone, Copy, Default)]
6413pub struct IterablePsampleAttrs<'a> {
6414 buf: &'a [u8],
6415 pos: usize,
6416 orig_loc: usize,
6417}
6418impl<'a> IterablePsampleAttrs<'a> {
6419 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
6420 Self {
6421 buf,
6422 pos: 0,
6423 orig_loc,
6424 }
6425 }
6426 pub fn get_buf(&self) -> &'a [u8] {
6427 self.buf
6428 }
6429}
6430impl<'a> Iterator for IterablePsampleAttrs<'a> {
6431 type Item = Result<PsampleAttrs<'a>, ErrorContext>;
6432 fn next(&mut self) -> Option<Self::Item> {
6433 let pos = self.pos;
6434 let mut r#type;
6435 loop {
6436 r#type = None;
6437 if self.buf.len() == self.pos {
6438 return None;
6439 }
6440 let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
6441 break;
6442 };
6443 r#type = Some(header.r#type);
6444 let res = match header.r#type {
6445 1u16 => PsampleAttrs::Group({
6446 let res = parse_u32(next);
6447 let Some(val) = res else { break };
6448 val
6449 }),
6450 2u16 => PsampleAttrs::Cookie({
6451 let res = Some(next);
6452 let Some(val) = res else { break };
6453 val
6454 }),
6455 n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
6456 n => continue,
6457 };
6458 return Some(Ok(res));
6459 }
6460 Some(Err(ErrorContext::new(
6461 "PsampleAttrs",
6462 r#type.and_then(|t| PsampleAttrs::attr_from_type(t)),
6463 self.orig_loc,
6464 self.buf.as_ptr().wrapping_add(pos) as usize,
6465 )))
6466 }
6467}
6468impl<'a> std::fmt::Debug for IterablePsampleAttrs<'_> {
6469 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
6470 let mut fmt = f.debug_struct("PsampleAttrs");
6471 for attr in self.clone() {
6472 let attr = match attr {
6473 Ok(a) => a,
6474 Err(err) => {
6475 fmt.finish()?;
6476 f.write_str("Err(")?;
6477 err.fmt(f)?;
6478 return f.write_str(")");
6479 }
6480 };
6481 match attr {
6482 PsampleAttrs::Group(val) => fmt.field("Group", &val),
6483 PsampleAttrs::Cookie(val) => fmt.field("Cookie", &val),
6484 };
6485 }
6486 fmt.finish()
6487 }
6488}
6489impl IterablePsampleAttrs<'_> {
6490 pub fn lookup_attr(
6491 &self,
6492 offset: usize,
6493 missing_type: Option<u16>,
6494 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
6495 let mut stack = Vec::new();
6496 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
6497 if missing_type.is_some() && cur == offset {
6498 stack.push(("PsampleAttrs", offset));
6499 return (
6500 stack,
6501 missing_type.and_then(|t| PsampleAttrs::attr_from_type(t)),
6502 );
6503 }
6504 if cur > offset || cur + self.buf.len() < offset {
6505 return (stack, None);
6506 }
6507 let mut attrs = self.clone();
6508 let mut last_off = cur + attrs.pos;
6509 while let Some(attr) = attrs.next() {
6510 let Ok(attr) = attr else { break };
6511 match attr {
6512 PsampleAttrs::Group(val) => {
6513 if last_off == offset {
6514 stack.push(("Group", last_off));
6515 break;
6516 }
6517 }
6518 PsampleAttrs::Cookie(val) => {
6519 if last_off == offset {
6520 stack.push(("Cookie", last_off));
6521 break;
6522 }
6523 }
6524 _ => {}
6525 };
6526 last_off = cur + attrs.pos;
6527 }
6528 if !stack.is_empty() {
6529 stack.push(("PsampleAttrs", cur));
6530 }
6531 (stack, None)
6532 }
6533}
6534pub struct PushFlowAttrs<Prev: Rec> {
6535 pub(crate) prev: Option<Prev>,
6536 pub(crate) header_offset: Option<usize>,
6537}
6538impl<Prev: Rec> Rec for PushFlowAttrs<Prev> {
6539 fn as_rec_mut(&mut self) -> &mut Vec<u8> {
6540 self.prev.as_mut().unwrap().as_rec_mut()
6541 }
6542 fn as_rec(&self) -> &Vec<u8> {
6543 self.prev.as_ref().unwrap().as_rec()
6544 }
6545}
6546impl<Prev: Rec> PushFlowAttrs<Prev> {
6547 pub fn new(prev: Prev) -> Self {
6548 Self {
6549 prev: Some(prev),
6550 header_offset: None,
6551 }
6552 }
6553 pub fn end_nested(mut self) -> Prev {
6554 let mut prev = self.prev.take().unwrap();
6555 if let Some(header_offset) = &self.header_offset {
6556 finalize_nested_header(prev.as_rec_mut(), *header_offset);
6557 }
6558 prev
6559 }
6560 #[doc = "Nested attributes specifying the flow key\\. Always present in\nnotifications\\. Required for all requests (except dumps)\\.\n"]
6561 pub fn nested_key(mut self) -> PushKeyAttrs<Self> {
6562 let header_offset = push_nested_header(self.as_rec_mut(), 1u16);
6563 PushKeyAttrs {
6564 prev: Some(self),
6565 header_offset: Some(header_offset),
6566 }
6567 }
6568 #[doc = "Nested attributes specifying the actions to take for packets that\nmatch the key\\. Always present in notifications\\. Required for\nOVS\\_FLOW\\_CMD\\_NEW requests, optional for OVS\\_FLOW\\_CMD\\_SET requests\\. An\nOVS\\_FLOW\\_CMD\\_SET without OVS\\_FLOW\\_ATTR\\_ACTIONS will not modify the\nactions\\. To clear the actions, an OVS\\_FLOW\\_ATTR\\_ACTIONS without any\nnested attributes must be given\\.\n"]
6569 pub fn nested_actions(mut self) -> PushActionAttrs<Self> {
6570 let header_offset = push_nested_header(self.as_rec_mut(), 2u16);
6571 PushActionAttrs {
6572 prev: Some(self),
6573 header_offset: Some(header_offset),
6574 }
6575 }
6576 #[doc = "Statistics for this flow\\. Present in notifications if the stats would\nbe nonzero\\. Ignored in requests\\.\n"]
6577 pub fn push_stats(mut self, value: OvsFlowStats) -> Self {
6578 push_header(self.as_rec_mut(), 3u16, value.as_slice().len() as u16);
6579 self.as_rec_mut().extend(value.as_slice());
6580 self
6581 }
6582 #[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"]
6583 pub fn push_tcp_flags(mut self, value: u8) -> Self {
6584 push_header(self.as_rec_mut(), 4u16, 1 as u16);
6585 self.as_rec_mut().extend(value.to_ne_bytes());
6586 self
6587 }
6588 #[doc = "A 64\\-bit integer giving the time, in milliseconds on the system\nmonotonic clock, at which a packet was last processed for this\nflow\\. Only present in notifications if a packet has been processed for\nthis flow\\. Ignored in requests\\.\n"]
6589 pub fn push_used(mut self, value: u64) -> Self {
6590 push_header(self.as_rec_mut(), 5u16, 8 as u16);
6591 self.as_rec_mut().extend(value.to_ne_bytes());
6592 self
6593 }
6594 #[doc = "If present in a OVS\\_FLOW\\_CMD\\_SET request, clears the last\\-used time,\naccumulated TCP flags, and statistics for this flow\\. Otherwise\nignored in requests\\. Never present in notifications\\.\n"]
6595 pub fn push_clear(mut self, value: ()) -> Self {
6596 push_header(self.as_rec_mut(), 6u16, 0 as u16);
6597 self
6598 }
6599 #[doc = "Nested attributes specifying the mask bits for wildcarded flow\nmatch\\. Mask bit value '1' specifies exact match with corresponding\nflow key bit, while mask bit value '0' specifies a wildcarded\nmatch\\. Omitting attribute is treated as wildcarding all corresponding\nfields\\. Optional for all requests\\. If not present, all flow key bits\nare exact match bits\\.\n"]
6600 pub fn nested_mask(mut self) -> PushKeyAttrs<Self> {
6601 let header_offset = push_nested_header(self.as_rec_mut(), 7u16);
6602 PushKeyAttrs {
6603 prev: Some(self),
6604 header_offset: Some(header_offset),
6605 }
6606 }
6607 #[doc = "Flow operation is a feature probe, error logging should be suppressed\\.\n"]
6608 pub fn push_probe(mut self, value: &[u8]) -> Self {
6609 push_header(self.as_rec_mut(), 8u16, value.len() as u16);
6610 self.as_rec_mut().extend(value);
6611 self
6612 }
6613 #[doc = "A value between 1\\-16 octets specifying a unique identifier for the\nflow\\. Causes the flow to be indexed by this value rather than the\nvalue of the OVS\\_FLOW\\_ATTR\\_KEY attribute\\. Optional for all\nrequests\\. Present in notifications if the flow was created with this\nattribute\\.\n"]
6614 pub fn push_ufid(mut self, value: &[u8]) -> Self {
6615 push_header(self.as_rec_mut(), 9u16, value.len() as u16);
6616 self.as_rec_mut().extend(value);
6617 self
6618 }
6619 #[doc = "A 32\\-bit value of ORed flags that provide alternative semantics for\nflow installation and retrieval\\. Optional for all requests\\.\n\nAssociated type: [`OvsUfidFlags`] (enum)"]
6620 pub fn push_ufid_flags(mut self, value: u32) -> Self {
6621 push_header(self.as_rec_mut(), 10u16, 4 as u16);
6622 self.as_rec_mut().extend(value.to_ne_bytes());
6623 self
6624 }
6625 pub fn push_pad(mut self, value: &[u8]) -> Self {
6626 push_header(self.as_rec_mut(), 11u16, value.len() as u16);
6627 self.as_rec_mut().extend(value);
6628 self
6629 }
6630}
6631impl<Prev: Rec> Drop for PushFlowAttrs<Prev> {
6632 fn drop(&mut self) {
6633 if let Some(prev) = &mut self.prev {
6634 if let Some(header_offset) = &self.header_offset {
6635 finalize_nested_header(prev.as_rec_mut(), *header_offset);
6636 }
6637 }
6638 }
6639}
6640pub struct PushKeyAttrs<Prev: Rec> {
6641 pub(crate) prev: Option<Prev>,
6642 pub(crate) header_offset: Option<usize>,
6643}
6644impl<Prev: Rec> Rec for PushKeyAttrs<Prev> {
6645 fn as_rec_mut(&mut self) -> &mut Vec<u8> {
6646 self.prev.as_mut().unwrap().as_rec_mut()
6647 }
6648 fn as_rec(&self) -> &Vec<u8> {
6649 self.prev.as_ref().unwrap().as_rec()
6650 }
6651}
6652impl<Prev: Rec> PushKeyAttrs<Prev> {
6653 pub fn new(prev: Prev) -> Self {
6654 Self {
6655 prev: Some(prev),
6656 header_offset: None,
6657 }
6658 }
6659 pub fn end_nested(mut self) -> Prev {
6660 let mut prev = self.prev.take().unwrap();
6661 if let Some(header_offset) = &self.header_offset {
6662 finalize_nested_header(prev.as_rec_mut(), *header_offset);
6663 }
6664 prev
6665 }
6666 pub fn nested_encap(mut self) -> PushKeyAttrs<Self> {
6667 let header_offset = push_nested_header(self.as_rec_mut(), 1u16);
6668 PushKeyAttrs {
6669 prev: Some(self),
6670 header_offset: Some(header_offset),
6671 }
6672 }
6673 pub fn push_priority(mut self, value: u32) -> Self {
6674 push_header(self.as_rec_mut(), 2u16, 4 as u16);
6675 self.as_rec_mut().extend(value.to_ne_bytes());
6676 self
6677 }
6678 pub fn push_in_port(mut self, value: u32) -> Self {
6679 push_header(self.as_rec_mut(), 3u16, 4 as u16);
6680 self.as_rec_mut().extend(value.to_ne_bytes());
6681 self
6682 }
6683 #[doc = "struct ovs\\_key\\_ethernet"]
6684 pub fn push_ethernet(mut self, value: OvsKeyEthernet) -> Self {
6685 push_header(self.as_rec_mut(), 4u16, value.as_slice().len() as u16);
6686 self.as_rec_mut().extend(value.as_slice());
6687 self
6688 }
6689 pub fn push_vlan(mut self, value: u16) -> Self {
6690 push_header(self.as_rec_mut(), 5u16, 2 as u16);
6691 self.as_rec_mut().extend(value.to_be_bytes());
6692 self
6693 }
6694 pub fn push_ethertype(mut self, value: u16) -> Self {
6695 push_header(self.as_rec_mut(), 6u16, 2 as u16);
6696 self.as_rec_mut().extend(value.to_be_bytes());
6697 self
6698 }
6699 pub fn push_ipv4(mut self, value: OvsKeyIpv4) -> Self {
6700 push_header(self.as_rec_mut(), 7u16, value.as_slice().len() as u16);
6701 self.as_rec_mut().extend(value.as_slice());
6702 self
6703 }
6704 #[doc = "struct ovs\\_key\\_ipv6"]
6705 pub fn push_ipv6(mut self, value: OvsKeyIpv6) -> Self {
6706 push_header(self.as_rec_mut(), 8u16, value.as_slice().len() as u16);
6707 self.as_rec_mut().extend(value.as_slice());
6708 self
6709 }
6710 pub fn push_tcp(mut self, value: OvsKeyTcp) -> Self {
6711 push_header(self.as_rec_mut(), 9u16, value.as_slice().len() as u16);
6712 self.as_rec_mut().extend(value.as_slice());
6713 self
6714 }
6715 pub fn push_udp(mut self, value: OvsKeyUdp) -> Self {
6716 push_header(self.as_rec_mut(), 10u16, value.as_slice().len() as u16);
6717 self.as_rec_mut().extend(value.as_slice());
6718 self
6719 }
6720 pub fn push_icmp(mut self, value: OvsKeyIcmp) -> Self {
6721 push_header(self.as_rec_mut(), 11u16, value.as_slice().len() as u16);
6722 self.as_rec_mut().extend(value.as_slice());
6723 self
6724 }
6725 pub fn push_icmpv6(mut self, value: OvsKeyIcmp) -> Self {
6726 push_header(self.as_rec_mut(), 12u16, value.as_slice().len() as u16);
6727 self.as_rec_mut().extend(value.as_slice());
6728 self
6729 }
6730 #[doc = "struct ovs\\_key\\_arp"]
6731 pub fn push_arp(mut self, value: OvsKeyArp) -> Self {
6732 push_header(self.as_rec_mut(), 13u16, value.as_slice().len() as u16);
6733 self.as_rec_mut().extend(value.as_slice());
6734 self
6735 }
6736 #[doc = "struct ovs\\_key\\_nd"]
6737 pub fn push_nd(mut self, value: OvsKeyNd) -> Self {
6738 push_header(self.as_rec_mut(), 14u16, value.as_slice().len() as u16);
6739 self.as_rec_mut().extend(value.as_slice());
6740 self
6741 }
6742 pub fn push_skb_mark(mut self, value: u32) -> Self {
6743 push_header(self.as_rec_mut(), 15u16, 4 as u16);
6744 self.as_rec_mut().extend(value.to_ne_bytes());
6745 self
6746 }
6747 pub fn nested_tunnel(mut self) -> PushTunnelKeyAttrs<Self> {
6748 let header_offset = push_nested_header(self.as_rec_mut(), 16u16);
6749 PushTunnelKeyAttrs {
6750 prev: Some(self),
6751 header_offset: Some(header_offset),
6752 }
6753 }
6754 pub fn push_sctp(mut self, value: OvsKeySctp) -> Self {
6755 push_header(self.as_rec_mut(), 17u16, value.as_slice().len() as u16);
6756 self.as_rec_mut().extend(value.as_slice());
6757 self
6758 }
6759 pub fn push_tcp_flags(mut self, value: u16) -> Self {
6760 push_header(self.as_rec_mut(), 18u16, 2 as u16);
6761 self.as_rec_mut().extend(value.to_be_bytes());
6762 self
6763 }
6764 #[doc = "Value 0 indicates the hash is not computed by the datapath\\."]
6765 pub fn push_dp_hash(mut self, value: u32) -> Self {
6766 push_header(self.as_rec_mut(), 19u16, 4 as u16);
6767 self.as_rec_mut().extend(value.to_ne_bytes());
6768 self
6769 }
6770 pub fn push_recirc_id(mut self, value: u32) -> Self {
6771 push_header(self.as_rec_mut(), 20u16, 4 as u16);
6772 self.as_rec_mut().extend(value.to_ne_bytes());
6773 self
6774 }
6775 pub fn push_mpls(mut self, value: OvsKeyMpls) -> Self {
6776 push_header(self.as_rec_mut(), 21u16, value.as_slice().len() as u16);
6777 self.as_rec_mut().extend(value.as_slice());
6778 self
6779 }
6780 #[doc = "Associated type: [`CtStateFlags`] (1 bit per enumeration)"]
6781 pub fn push_ct_state(mut self, value: u32) -> Self {
6782 push_header(self.as_rec_mut(), 22u16, 4 as u16);
6783 self.as_rec_mut().extend(value.to_ne_bytes());
6784 self
6785 }
6786 #[doc = "connection tracking zone"]
6787 pub fn push_ct_zone(mut self, value: u16) -> Self {
6788 push_header(self.as_rec_mut(), 23u16, 2 as u16);
6789 self.as_rec_mut().extend(value.to_ne_bytes());
6790 self
6791 }
6792 #[doc = "connection tracking mark"]
6793 pub fn push_ct_mark(mut self, value: u32) -> Self {
6794 push_header(self.as_rec_mut(), 24u16, 4 as u16);
6795 self.as_rec_mut().extend(value.to_ne_bytes());
6796 self
6797 }
6798 #[doc = "16\\-octet connection tracking label"]
6799 pub fn push_ct_labels(mut self, value: &[u8]) -> Self {
6800 push_header(self.as_rec_mut(), 25u16, value.len() as u16);
6801 self.as_rec_mut().extend(value);
6802 self
6803 }
6804 pub fn push_ct_orig_tuple_ipv4(mut self, value: OvsKeyCtTupleIpv4) -> Self {
6805 push_header(self.as_rec_mut(), 26u16, value.as_slice().len() as u16);
6806 self.as_rec_mut().extend(value.as_slice());
6807 self
6808 }
6809 #[doc = "struct ovs\\_key\\_ct\\_tuple\\_ipv6"]
6810 pub fn push_ct_orig_tuple_ipv6(mut self, value: &[u8]) -> Self {
6811 push_header(self.as_rec_mut(), 27u16, value.len() as u16);
6812 self.as_rec_mut().extend(value);
6813 self
6814 }
6815 pub fn nested_nsh(mut self) -> PushOvsNshKeyAttrs<Self> {
6816 let header_offset = push_nested_header(self.as_rec_mut(), 28u16);
6817 PushOvsNshKeyAttrs {
6818 prev: Some(self),
6819 header_offset: Some(header_offset),
6820 }
6821 }
6822 #[doc = "Should not be sent to the kernel"]
6823 pub fn push_packet_type(mut self, value: u32) -> Self {
6824 push_header(self.as_rec_mut(), 29u16, 4 as u16);
6825 self.as_rec_mut().extend(value.to_be_bytes());
6826 self
6827 }
6828 #[doc = "Should not be sent to the kernel"]
6829 pub fn push_nd_extensions(mut self, value: &[u8]) -> Self {
6830 push_header(self.as_rec_mut(), 30u16, value.len() as u16);
6831 self.as_rec_mut().extend(value);
6832 self
6833 }
6834 #[doc = "struct ip\\_tunnel\\_info"]
6835 pub fn push_tunnel_info(mut self, value: &[u8]) -> Self {
6836 push_header(self.as_rec_mut(), 31u16, value.len() as u16);
6837 self.as_rec_mut().extend(value);
6838 self
6839 }
6840 #[doc = "struct ovs\\_key\\_ipv6\\_exthdr"]
6841 pub fn push_ipv6_exthdrs(mut self, value: OvsKeyIpv6Exthdrs) -> Self {
6842 push_header(self.as_rec_mut(), 32u16, value.as_slice().len() as u16);
6843 self.as_rec_mut().extend(value.as_slice());
6844 self
6845 }
6846}
6847impl<Prev: Rec> Drop for PushKeyAttrs<Prev> {
6848 fn drop(&mut self) {
6849 if let Some(prev) = &mut self.prev {
6850 if let Some(header_offset) = &self.header_offset {
6851 finalize_nested_header(prev.as_rec_mut(), *header_offset);
6852 }
6853 }
6854 }
6855}
6856pub struct PushActionAttrs<Prev: Rec> {
6857 pub(crate) prev: Option<Prev>,
6858 pub(crate) header_offset: Option<usize>,
6859}
6860impl<Prev: Rec> Rec for PushActionAttrs<Prev> {
6861 fn as_rec_mut(&mut self) -> &mut Vec<u8> {
6862 self.prev.as_mut().unwrap().as_rec_mut()
6863 }
6864 fn as_rec(&self) -> &Vec<u8> {
6865 self.prev.as_ref().unwrap().as_rec()
6866 }
6867}
6868impl<Prev: Rec> PushActionAttrs<Prev> {
6869 pub fn new(prev: Prev) -> Self {
6870 Self {
6871 prev: Some(prev),
6872 header_offset: None,
6873 }
6874 }
6875 pub fn end_nested(mut self) -> Prev {
6876 let mut prev = self.prev.take().unwrap();
6877 if let Some(header_offset) = &self.header_offset {
6878 finalize_nested_header(prev.as_rec_mut(), *header_offset);
6879 }
6880 prev
6881 }
6882 #[doc = "ovs port number in datapath"]
6883 pub fn push_output(mut self, value: u32) -> Self {
6884 push_header(self.as_rec_mut(), 1u16, 4 as u16);
6885 self.as_rec_mut().extend(value.to_ne_bytes());
6886 self
6887 }
6888 pub fn nested_userspace(mut self) -> PushUserspaceAttrs<Self> {
6889 let header_offset = push_nested_header(self.as_rec_mut(), 2u16);
6890 PushUserspaceAttrs {
6891 prev: Some(self),
6892 header_offset: Some(header_offset),
6893 }
6894 }
6895 #[doc = "Replaces the contents of an existing header\\. The single nested\nattribute specifies a header to modify and its value\\.\n"]
6896 pub fn nested_set(mut self) -> PushKeyAttrs<Self> {
6897 let header_offset = push_nested_header(self.as_rec_mut(), 3u16);
6898 PushKeyAttrs {
6899 prev: Some(self),
6900 header_offset: Some(header_offset),
6901 }
6902 }
6903 #[doc = "Push a new outermost 802\\.1Q or 802\\.1ad header onto the packet\\."]
6904 pub fn push_push_vlan(mut self, value: OvsActionPushVlan) -> Self {
6905 push_header(self.as_rec_mut(), 4u16, value.as_slice().len() as u16);
6906 self.as_rec_mut().extend(value.as_slice());
6907 self
6908 }
6909 #[doc = "Pop the outermost 802\\.1Q or 802\\.1ad header from the packet\\."]
6910 pub fn push_pop_vlan(mut self, value: ()) -> Self {
6911 push_header(self.as_rec_mut(), 5u16, 0 as u16);
6912 self
6913 }
6914 #[doc = "Probabilistically executes actions, as specified in the nested\nattributes\\.\n"]
6915 pub fn nested_sample(mut self) -> PushSampleAttrs<Self> {
6916 let header_offset = push_nested_header(self.as_rec_mut(), 6u16);
6917 PushSampleAttrs {
6918 prev: Some(self),
6919 header_offset: Some(header_offset),
6920 }
6921 }
6922 #[doc = "recirc id"]
6923 pub fn push_recirc(mut self, value: u32) -> Self {
6924 push_header(self.as_rec_mut(), 7u16, 4 as u16);
6925 self.as_rec_mut().extend(value.to_ne_bytes());
6926 self
6927 }
6928 pub fn push_hash(mut self, value: OvsActionHash) -> Self {
6929 push_header(self.as_rec_mut(), 8u16, value.as_slice().len() as u16);
6930 self.as_rec_mut().extend(value.as_slice());
6931 self
6932 }
6933 #[doc = "Push a new MPLS label stack entry onto the top of the packets MPLS\nlabel stack\\. 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"]
6934 pub fn push_push_mpls(mut self, value: OvsActionPushMpls) -> Self {
6935 push_header(self.as_rec_mut(), 9u16, value.as_slice().len() as u16);
6936 self.as_rec_mut().extend(value.as_slice());
6937 self
6938 }
6939 #[doc = "ethertype"]
6940 pub fn push_pop_mpls(mut self, value: u16) -> Self {
6941 push_header(self.as_rec_mut(), 10u16, 2 as u16);
6942 self.as_rec_mut().extend(value.to_be_bytes());
6943 self
6944 }
6945 #[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\nthe packet header field, rest of the bits are left unchanged\\. The\nnon\\-masked value bits must be passed in as zeroes\\. Masking is not\nsupported for the OVS\\_KEY\\_ATTR\\_TUNNEL attribute\\.\n"]
6946 pub fn nested_set_masked(mut self) -> PushKeyAttrs<Self> {
6947 let header_offset = push_nested_header(self.as_rec_mut(), 11u16);
6948 PushKeyAttrs {
6949 prev: Some(self),
6950 header_offset: Some(header_offset),
6951 }
6952 }
6953 #[doc = "Track the connection\\. Populate the conntrack\\-related entries\nin the flow key\\.\n"]
6954 pub fn nested_ct(mut self) -> PushCtAttrs<Self> {
6955 let header_offset = push_nested_header(self.as_rec_mut(), 12u16);
6956 PushCtAttrs {
6957 prev: Some(self),
6958 header_offset: Some(header_offset),
6959 }
6960 }
6961 #[doc = "struct ovs\\_action\\_trunc is a u32 max length"]
6962 pub fn push_trunc(mut self, value: u32) -> Self {
6963 push_header(self.as_rec_mut(), 13u16, 4 as u16);
6964 self.as_rec_mut().extend(value.to_ne_bytes());
6965 self
6966 }
6967 #[doc = "struct ovs\\_action\\_push\\_eth"]
6968 pub fn push_push_eth(mut self, value: &[u8]) -> Self {
6969 push_header(self.as_rec_mut(), 14u16, value.len() as u16);
6970 self.as_rec_mut().extend(value);
6971 self
6972 }
6973 pub fn push_pop_eth(mut self, value: ()) -> Self {
6974 push_header(self.as_rec_mut(), 15u16, 0 as u16);
6975 self
6976 }
6977 pub fn push_ct_clear(mut self, value: ()) -> Self {
6978 push_header(self.as_rec_mut(), 16u16, 0 as u16);
6979 self
6980 }
6981 #[doc = "Push NSH header to the packet\\.\n"]
6982 pub fn nested_push_nsh(mut self) -> PushOvsNshKeyAttrs<Self> {
6983 let header_offset = push_nested_header(self.as_rec_mut(), 17u16);
6984 PushOvsNshKeyAttrs {
6985 prev: Some(self),
6986 header_offset: Some(header_offset),
6987 }
6988 }
6989 #[doc = "Pop the outermost NSH header off the packet\\.\n"]
6990 pub fn push_pop_nsh(mut self, value: ()) -> Self {
6991 push_header(self.as_rec_mut(), 18u16, 0 as u16);
6992 self
6993 }
6994 #[doc = "Run packet through a meter, which may drop the packet, or modify the\npacket (e\\.g\\., change the DSCP field)\n"]
6995 pub fn push_meter(mut self, value: u32) -> Self {
6996 push_header(self.as_rec_mut(), 19u16, 4 as u16);
6997 self.as_rec_mut().extend(value.to_ne_bytes());
6998 self
6999 }
7000 #[doc = "Make a copy of the packet and execute a list of actions without\naffecting the original packet and key\\.\n"]
7001 pub fn nested_clone(mut self) -> PushActionAttrs<Self> {
7002 let header_offset = push_nested_header(self.as_rec_mut(), 20u16);
7003 PushActionAttrs {
7004 prev: Some(self),
7005 header_offset: Some(header_offset),
7006 }
7007 }
7008 #[doc = "Check the packet length and execute a set of actions if greater than\nthe specified packet length, else execute another set of actions\\.\n"]
7009 pub fn nested_check_pkt_len(mut self) -> PushCheckPktLenAttrs<Self> {
7010 let header_offset = push_nested_header(self.as_rec_mut(), 21u16);
7011 PushCheckPktLenAttrs {
7012 prev: Some(self),
7013 header_offset: Some(header_offset),
7014 }
7015 }
7016 #[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"]
7017 pub fn push_add_mpls(mut self, value: OvsActionAddMpls) -> Self {
7018 push_header(self.as_rec_mut(), 22u16, value.as_slice().len() as u16);
7019 self.as_rec_mut().extend(value.as_slice());
7020 self
7021 }
7022 pub fn nested_dec_ttl(mut self) -> PushDecTtlAttrs<Self> {
7023 let header_offset = push_nested_header(self.as_rec_mut(), 23u16);
7024 PushDecTtlAttrs {
7025 prev: Some(self),
7026 header_offset: Some(header_offset),
7027 }
7028 }
7029 #[doc = "Sends a packet sample to psample for external observation\\.\n"]
7030 pub fn nested_psample(mut self) -> PushPsampleAttrs<Self> {
7031 let header_offset = push_nested_header(self.as_rec_mut(), 24u16);
7032 PushPsampleAttrs {
7033 prev: Some(self),
7034 header_offset: Some(header_offset),
7035 }
7036 }
7037}
7038impl<Prev: Rec> Drop for PushActionAttrs<Prev> {
7039 fn drop(&mut self) {
7040 if let Some(prev) = &mut self.prev {
7041 if let Some(header_offset) = &self.header_offset {
7042 finalize_nested_header(prev.as_rec_mut(), *header_offset);
7043 }
7044 }
7045 }
7046}
7047pub struct PushTunnelKeyAttrs<Prev: Rec> {
7048 pub(crate) prev: Option<Prev>,
7049 pub(crate) header_offset: Option<usize>,
7050}
7051impl<Prev: Rec> Rec for PushTunnelKeyAttrs<Prev> {
7052 fn as_rec_mut(&mut self) -> &mut Vec<u8> {
7053 self.prev.as_mut().unwrap().as_rec_mut()
7054 }
7055 fn as_rec(&self) -> &Vec<u8> {
7056 self.prev.as_ref().unwrap().as_rec()
7057 }
7058}
7059impl<Prev: Rec> PushTunnelKeyAttrs<Prev> {
7060 pub fn new(prev: Prev) -> Self {
7061 Self {
7062 prev: Some(prev),
7063 header_offset: None,
7064 }
7065 }
7066 pub fn end_nested(mut self) -> Prev {
7067 let mut prev = self.prev.take().unwrap();
7068 if let Some(header_offset) = &self.header_offset {
7069 finalize_nested_header(prev.as_rec_mut(), *header_offset);
7070 }
7071 prev
7072 }
7073 pub fn push_id(mut self, value: u64) -> Self {
7074 push_header(self.as_rec_mut(), 0u16, 8 as u16);
7075 self.as_rec_mut().extend(value.to_be_bytes());
7076 self
7077 }
7078 pub fn push_ipv4_src(mut self, value: u32) -> Self {
7079 push_header(self.as_rec_mut(), 1u16, 4 as u16);
7080 self.as_rec_mut().extend(value.to_be_bytes());
7081 self
7082 }
7083 pub fn push_ipv4_dst(mut self, value: u32) -> Self {
7084 push_header(self.as_rec_mut(), 2u16, 4 as u16);
7085 self.as_rec_mut().extend(value.to_be_bytes());
7086 self
7087 }
7088 pub fn push_tos(mut self, value: u8) -> Self {
7089 push_header(self.as_rec_mut(), 3u16, 1 as u16);
7090 self.as_rec_mut().extend(value.to_ne_bytes());
7091 self
7092 }
7093 pub fn push_ttl(mut self, value: u8) -> Self {
7094 push_header(self.as_rec_mut(), 4u16, 1 as u16);
7095 self.as_rec_mut().extend(value.to_ne_bytes());
7096 self
7097 }
7098 pub fn push_dont_fragment(mut self, value: ()) -> Self {
7099 push_header(self.as_rec_mut(), 5u16, 0 as u16);
7100 self
7101 }
7102 pub fn push_csum(mut self, value: ()) -> Self {
7103 push_header(self.as_rec_mut(), 6u16, 0 as u16);
7104 self
7105 }
7106 pub fn push_oam(mut self, value: ()) -> Self {
7107 push_header(self.as_rec_mut(), 7u16, 0 as u16);
7108 self
7109 }
7110 pub fn push_geneve_opts(mut self, value: &[u8]) -> Self {
7111 push_header(self.as_rec_mut(), 8u16, value.len() as u16);
7112 self.as_rec_mut().extend(value);
7113 self
7114 }
7115 pub fn push_tp_src(mut self, value: u16) -> Self {
7116 push_header(self.as_rec_mut(), 9u16, 2 as u16);
7117 self.as_rec_mut().extend(value.to_be_bytes());
7118 self
7119 }
7120 pub fn push_tp_dst(mut self, value: u16) -> Self {
7121 push_header(self.as_rec_mut(), 10u16, 2 as u16);
7122 self.as_rec_mut().extend(value.to_be_bytes());
7123 self
7124 }
7125 pub fn nested_vxlan_opts(mut self) -> PushVxlanExtAttrs<Self> {
7126 let header_offset = push_nested_header(self.as_rec_mut(), 11u16);
7127 PushVxlanExtAttrs {
7128 prev: Some(self),
7129 header_offset: Some(header_offset),
7130 }
7131 }
7132 #[doc = "struct in6\\_addr source IPv6 address\n"]
7133 pub fn push_ipv6_src(mut self, value: &[u8]) -> Self {
7134 push_header(self.as_rec_mut(), 12u16, value.len() as u16);
7135 self.as_rec_mut().extend(value);
7136 self
7137 }
7138 #[doc = "struct in6\\_addr destination IPv6 address\n"]
7139 pub fn push_ipv6_dst(mut self, value: &[u8]) -> Self {
7140 push_header(self.as_rec_mut(), 13u16, value.len() as u16);
7141 self.as_rec_mut().extend(value);
7142 self
7143 }
7144 pub fn push_pad(mut self, value: &[u8]) -> Self {
7145 push_header(self.as_rec_mut(), 14u16, value.len() as u16);
7146 self.as_rec_mut().extend(value);
7147 self
7148 }
7149 #[doc = "struct erspan\\_metadata\n"]
7150 pub fn push_erspan_opts(mut self, value: &[u8]) -> Self {
7151 push_header(self.as_rec_mut(), 15u16, value.len() as u16);
7152 self.as_rec_mut().extend(value);
7153 self
7154 }
7155 pub fn push_ipv4_info_bridge(mut self, value: ()) -> Self {
7156 push_header(self.as_rec_mut(), 16u16, 0 as u16);
7157 self
7158 }
7159}
7160impl<Prev: Rec> Drop for PushTunnelKeyAttrs<Prev> {
7161 fn drop(&mut self) {
7162 if let Some(prev) = &mut self.prev {
7163 if let Some(header_offset) = &self.header_offset {
7164 finalize_nested_header(prev.as_rec_mut(), *header_offset);
7165 }
7166 }
7167 }
7168}
7169pub struct PushCheckPktLenAttrs<Prev: Rec> {
7170 pub(crate) prev: Option<Prev>,
7171 pub(crate) header_offset: Option<usize>,
7172}
7173impl<Prev: Rec> Rec for PushCheckPktLenAttrs<Prev> {
7174 fn as_rec_mut(&mut self) -> &mut Vec<u8> {
7175 self.prev.as_mut().unwrap().as_rec_mut()
7176 }
7177 fn as_rec(&self) -> &Vec<u8> {
7178 self.prev.as_ref().unwrap().as_rec()
7179 }
7180}
7181impl<Prev: Rec> PushCheckPktLenAttrs<Prev> {
7182 pub fn new(prev: Prev) -> Self {
7183 Self {
7184 prev: Some(prev),
7185 header_offset: None,
7186 }
7187 }
7188 pub fn end_nested(mut self) -> Prev {
7189 let mut prev = self.prev.take().unwrap();
7190 if let Some(header_offset) = &self.header_offset {
7191 finalize_nested_header(prev.as_rec_mut(), *header_offset);
7192 }
7193 prev
7194 }
7195 pub fn push_pkt_len(mut self, value: u16) -> Self {
7196 push_header(self.as_rec_mut(), 1u16, 2 as u16);
7197 self.as_rec_mut().extend(value.to_ne_bytes());
7198 self
7199 }
7200 pub fn nested_actions_if_greater(mut self) -> PushActionAttrs<Self> {
7201 let header_offset = push_nested_header(self.as_rec_mut(), 2u16);
7202 PushActionAttrs {
7203 prev: Some(self),
7204 header_offset: Some(header_offset),
7205 }
7206 }
7207 pub fn nested_actions_if_less_equal(mut self) -> PushActionAttrs<Self> {
7208 let header_offset = push_nested_header(self.as_rec_mut(), 3u16);
7209 PushActionAttrs {
7210 prev: Some(self),
7211 header_offset: Some(header_offset),
7212 }
7213 }
7214}
7215impl<Prev: Rec> Drop for PushCheckPktLenAttrs<Prev> {
7216 fn drop(&mut self) {
7217 if let Some(prev) = &mut self.prev {
7218 if let Some(header_offset) = &self.header_offset {
7219 finalize_nested_header(prev.as_rec_mut(), *header_offset);
7220 }
7221 }
7222 }
7223}
7224pub struct PushSampleAttrs<Prev: Rec> {
7225 pub(crate) prev: Option<Prev>,
7226 pub(crate) header_offset: Option<usize>,
7227}
7228impl<Prev: Rec> Rec for PushSampleAttrs<Prev> {
7229 fn as_rec_mut(&mut self) -> &mut Vec<u8> {
7230 self.prev.as_mut().unwrap().as_rec_mut()
7231 }
7232 fn as_rec(&self) -> &Vec<u8> {
7233 self.prev.as_ref().unwrap().as_rec()
7234 }
7235}
7236impl<Prev: Rec> PushSampleAttrs<Prev> {
7237 pub fn new(prev: Prev) -> Self {
7238 Self {
7239 prev: Some(prev),
7240 header_offset: None,
7241 }
7242 }
7243 pub fn end_nested(mut self) -> Prev {
7244 let mut prev = self.prev.take().unwrap();
7245 if let Some(header_offset) = &self.header_offset {
7246 finalize_nested_header(prev.as_rec_mut(), *header_offset);
7247 }
7248 prev
7249 }
7250 pub fn push_probability(mut self, value: u32) -> Self {
7251 push_header(self.as_rec_mut(), 1u16, 4 as u16);
7252 self.as_rec_mut().extend(value.to_ne_bytes());
7253 self
7254 }
7255 pub fn nested_actions(mut self) -> PushActionAttrs<Self> {
7256 let header_offset = push_nested_header(self.as_rec_mut(), 2u16);
7257 PushActionAttrs {
7258 prev: Some(self),
7259 header_offset: Some(header_offset),
7260 }
7261 }
7262}
7263impl<Prev: Rec> Drop for PushSampleAttrs<Prev> {
7264 fn drop(&mut self) {
7265 if let Some(prev) = &mut self.prev {
7266 if let Some(header_offset) = &self.header_offset {
7267 finalize_nested_header(prev.as_rec_mut(), *header_offset);
7268 }
7269 }
7270 }
7271}
7272pub struct PushUserspaceAttrs<Prev: Rec> {
7273 pub(crate) prev: Option<Prev>,
7274 pub(crate) header_offset: Option<usize>,
7275}
7276impl<Prev: Rec> Rec for PushUserspaceAttrs<Prev> {
7277 fn as_rec_mut(&mut self) -> &mut Vec<u8> {
7278 self.prev.as_mut().unwrap().as_rec_mut()
7279 }
7280 fn as_rec(&self) -> &Vec<u8> {
7281 self.prev.as_ref().unwrap().as_rec()
7282 }
7283}
7284impl<Prev: Rec> PushUserspaceAttrs<Prev> {
7285 pub fn new(prev: Prev) -> Self {
7286 Self {
7287 prev: Some(prev),
7288 header_offset: None,
7289 }
7290 }
7291 pub fn end_nested(mut self) -> Prev {
7292 let mut prev = self.prev.take().unwrap();
7293 if let Some(header_offset) = &self.header_offset {
7294 finalize_nested_header(prev.as_rec_mut(), *header_offset);
7295 }
7296 prev
7297 }
7298 pub fn push_pid(mut self, value: u32) -> Self {
7299 push_header(self.as_rec_mut(), 1u16, 4 as u16);
7300 self.as_rec_mut().extend(value.to_ne_bytes());
7301 self
7302 }
7303 pub fn push_userdata(mut self, value: &[u8]) -> Self {
7304 push_header(self.as_rec_mut(), 2u16, value.len() as u16);
7305 self.as_rec_mut().extend(value);
7306 self
7307 }
7308 pub fn push_egress_tun_port(mut self, value: u32) -> Self {
7309 push_header(self.as_rec_mut(), 3u16, 4 as u16);
7310 self.as_rec_mut().extend(value.to_ne_bytes());
7311 self
7312 }
7313 pub fn push_actions(mut self, value: ()) -> Self {
7314 push_header(self.as_rec_mut(), 4u16, 0 as u16);
7315 self
7316 }
7317}
7318impl<Prev: Rec> Drop for PushUserspaceAttrs<Prev> {
7319 fn drop(&mut self) {
7320 if let Some(prev) = &mut self.prev {
7321 if let Some(header_offset) = &self.header_offset {
7322 finalize_nested_header(prev.as_rec_mut(), *header_offset);
7323 }
7324 }
7325 }
7326}
7327pub struct PushOvsNshKeyAttrs<Prev: Rec> {
7328 pub(crate) prev: Option<Prev>,
7329 pub(crate) header_offset: Option<usize>,
7330}
7331impl<Prev: Rec> Rec for PushOvsNshKeyAttrs<Prev> {
7332 fn as_rec_mut(&mut self) -> &mut Vec<u8> {
7333 self.prev.as_mut().unwrap().as_rec_mut()
7334 }
7335 fn as_rec(&self) -> &Vec<u8> {
7336 self.prev.as_ref().unwrap().as_rec()
7337 }
7338}
7339impl<Prev: Rec> PushOvsNshKeyAttrs<Prev> {
7340 pub fn new(prev: Prev) -> Self {
7341 Self {
7342 prev: Some(prev),
7343 header_offset: None,
7344 }
7345 }
7346 pub fn end_nested(mut self) -> Prev {
7347 let mut prev = self.prev.take().unwrap();
7348 if let Some(header_offset) = &self.header_offset {
7349 finalize_nested_header(prev.as_rec_mut(), *header_offset);
7350 }
7351 prev
7352 }
7353 pub fn push_base(mut self, value: &[u8]) -> Self {
7354 push_header(self.as_rec_mut(), 1u16, value.len() as u16);
7355 self.as_rec_mut().extend(value);
7356 self
7357 }
7358 pub fn push_md1(mut self, value: &[u8]) -> Self {
7359 push_header(self.as_rec_mut(), 2u16, value.len() as u16);
7360 self.as_rec_mut().extend(value);
7361 self
7362 }
7363 pub fn push_md2(mut self, value: &[u8]) -> Self {
7364 push_header(self.as_rec_mut(), 3u16, value.len() as u16);
7365 self.as_rec_mut().extend(value);
7366 self
7367 }
7368}
7369impl<Prev: Rec> Drop for PushOvsNshKeyAttrs<Prev> {
7370 fn drop(&mut self) {
7371 if let Some(prev) = &mut self.prev {
7372 if let Some(header_offset) = &self.header_offset {
7373 finalize_nested_header(prev.as_rec_mut(), *header_offset);
7374 }
7375 }
7376 }
7377}
7378pub struct PushCtAttrs<Prev: Rec> {
7379 pub(crate) prev: Option<Prev>,
7380 pub(crate) header_offset: Option<usize>,
7381}
7382impl<Prev: Rec> Rec for PushCtAttrs<Prev> {
7383 fn as_rec_mut(&mut self) -> &mut Vec<u8> {
7384 self.prev.as_mut().unwrap().as_rec_mut()
7385 }
7386 fn as_rec(&self) -> &Vec<u8> {
7387 self.prev.as_ref().unwrap().as_rec()
7388 }
7389}
7390impl<Prev: Rec> PushCtAttrs<Prev> {
7391 pub fn new(prev: Prev) -> Self {
7392 Self {
7393 prev: Some(prev),
7394 header_offset: None,
7395 }
7396 }
7397 pub fn end_nested(mut self) -> Prev {
7398 let mut prev = self.prev.take().unwrap();
7399 if let Some(header_offset) = &self.header_offset {
7400 finalize_nested_header(prev.as_rec_mut(), *header_offset);
7401 }
7402 prev
7403 }
7404 pub fn push_commit(mut self, value: ()) -> Self {
7405 push_header(self.as_rec_mut(), 1u16, 0 as u16);
7406 self
7407 }
7408 pub fn push_zone(mut self, value: u16) -> Self {
7409 push_header(self.as_rec_mut(), 2u16, 2 as u16);
7410 self.as_rec_mut().extend(value.to_ne_bytes());
7411 self
7412 }
7413 pub fn push_mark(mut self, value: &[u8]) -> Self {
7414 push_header(self.as_rec_mut(), 3u16, value.len() as u16);
7415 self.as_rec_mut().extend(value);
7416 self
7417 }
7418 pub fn push_labels(mut self, value: &[u8]) -> Self {
7419 push_header(self.as_rec_mut(), 4u16, value.len() as u16);
7420 self.as_rec_mut().extend(value);
7421 self
7422 }
7423 pub fn push_helper(mut self, value: &CStr) -> Self {
7424 push_header(
7425 self.as_rec_mut(),
7426 5u16,
7427 value.to_bytes_with_nul().len() as u16,
7428 );
7429 self.as_rec_mut().extend(value.to_bytes_with_nul());
7430 self
7431 }
7432 pub fn push_helper_bytes(mut self, value: &[u8]) -> Self {
7433 push_header(self.as_rec_mut(), 5u16, (value.len() + 1) as u16);
7434 self.as_rec_mut().extend(value);
7435 self.as_rec_mut().push(0);
7436 self
7437 }
7438 pub fn nested_nat(mut self) -> PushNatAttrs<Self> {
7439 let header_offset = push_nested_header(self.as_rec_mut(), 6u16);
7440 PushNatAttrs {
7441 prev: Some(self),
7442 header_offset: Some(header_offset),
7443 }
7444 }
7445 pub fn push_force_commit(mut self, value: ()) -> Self {
7446 push_header(self.as_rec_mut(), 7u16, 0 as u16);
7447 self
7448 }
7449 pub fn push_eventmask(mut self, value: u32) -> Self {
7450 push_header(self.as_rec_mut(), 8u16, 4 as u16);
7451 self.as_rec_mut().extend(value.to_ne_bytes());
7452 self
7453 }
7454 pub fn push_timeout(mut self, value: &CStr) -> Self {
7455 push_header(
7456 self.as_rec_mut(),
7457 9u16,
7458 value.to_bytes_with_nul().len() as u16,
7459 );
7460 self.as_rec_mut().extend(value.to_bytes_with_nul());
7461 self
7462 }
7463 pub fn push_timeout_bytes(mut self, value: &[u8]) -> Self {
7464 push_header(self.as_rec_mut(), 9u16, (value.len() + 1) as u16);
7465 self.as_rec_mut().extend(value);
7466 self.as_rec_mut().push(0);
7467 self
7468 }
7469}
7470impl<Prev: Rec> Drop for PushCtAttrs<Prev> {
7471 fn drop(&mut self) {
7472 if let Some(prev) = &mut self.prev {
7473 if let Some(header_offset) = &self.header_offset {
7474 finalize_nested_header(prev.as_rec_mut(), *header_offset);
7475 }
7476 }
7477 }
7478}
7479pub struct PushNatAttrs<Prev: Rec> {
7480 pub(crate) prev: Option<Prev>,
7481 pub(crate) header_offset: Option<usize>,
7482}
7483impl<Prev: Rec> Rec for PushNatAttrs<Prev> {
7484 fn as_rec_mut(&mut self) -> &mut Vec<u8> {
7485 self.prev.as_mut().unwrap().as_rec_mut()
7486 }
7487 fn as_rec(&self) -> &Vec<u8> {
7488 self.prev.as_ref().unwrap().as_rec()
7489 }
7490}
7491impl<Prev: Rec> PushNatAttrs<Prev> {
7492 pub fn new(prev: Prev) -> Self {
7493 Self {
7494 prev: Some(prev),
7495 header_offset: None,
7496 }
7497 }
7498 pub fn end_nested(mut self) -> Prev {
7499 let mut prev = self.prev.take().unwrap();
7500 if let Some(header_offset) = &self.header_offset {
7501 finalize_nested_header(prev.as_rec_mut(), *header_offset);
7502 }
7503 prev
7504 }
7505 pub fn push_src(mut self, value: ()) -> Self {
7506 push_header(self.as_rec_mut(), 1u16, 0 as u16);
7507 self
7508 }
7509 pub fn push_dst(mut self, value: ()) -> Self {
7510 push_header(self.as_rec_mut(), 2u16, 0 as u16);
7511 self
7512 }
7513 pub fn push_ip_min(mut self, value: &[u8]) -> Self {
7514 push_header(self.as_rec_mut(), 3u16, value.len() as u16);
7515 self.as_rec_mut().extend(value);
7516 self
7517 }
7518 pub fn push_ip_max(mut self, value: &[u8]) -> Self {
7519 push_header(self.as_rec_mut(), 4u16, value.len() as u16);
7520 self.as_rec_mut().extend(value);
7521 self
7522 }
7523 pub fn push_proto_min(mut self, value: u16) -> Self {
7524 push_header(self.as_rec_mut(), 5u16, 2 as u16);
7525 self.as_rec_mut().extend(value.to_ne_bytes());
7526 self
7527 }
7528 pub fn push_proto_max(mut self, value: u16) -> Self {
7529 push_header(self.as_rec_mut(), 6u16, 2 as u16);
7530 self.as_rec_mut().extend(value.to_ne_bytes());
7531 self
7532 }
7533 pub fn push_persistent(mut self, value: ()) -> Self {
7534 push_header(self.as_rec_mut(), 7u16, 0 as u16);
7535 self
7536 }
7537 pub fn push_proto_hash(mut self, value: ()) -> Self {
7538 push_header(self.as_rec_mut(), 8u16, 0 as u16);
7539 self
7540 }
7541 pub fn push_proto_random(mut self, value: ()) -> Self {
7542 push_header(self.as_rec_mut(), 9u16, 0 as u16);
7543 self
7544 }
7545}
7546impl<Prev: Rec> Drop for PushNatAttrs<Prev> {
7547 fn drop(&mut self) {
7548 if let Some(prev) = &mut self.prev {
7549 if let Some(header_offset) = &self.header_offset {
7550 finalize_nested_header(prev.as_rec_mut(), *header_offset);
7551 }
7552 }
7553 }
7554}
7555pub struct PushDecTtlAttrs<Prev: Rec> {
7556 pub(crate) prev: Option<Prev>,
7557 pub(crate) header_offset: Option<usize>,
7558}
7559impl<Prev: Rec> Rec for PushDecTtlAttrs<Prev> {
7560 fn as_rec_mut(&mut self) -> &mut Vec<u8> {
7561 self.prev.as_mut().unwrap().as_rec_mut()
7562 }
7563 fn as_rec(&self) -> &Vec<u8> {
7564 self.prev.as_ref().unwrap().as_rec()
7565 }
7566}
7567impl<Prev: Rec> PushDecTtlAttrs<Prev> {
7568 pub fn new(prev: Prev) -> Self {
7569 Self {
7570 prev: Some(prev),
7571 header_offset: None,
7572 }
7573 }
7574 pub fn end_nested(mut self) -> Prev {
7575 let mut prev = self.prev.take().unwrap();
7576 if let Some(header_offset) = &self.header_offset {
7577 finalize_nested_header(prev.as_rec_mut(), *header_offset);
7578 }
7579 prev
7580 }
7581 pub fn nested_action(mut self) -> PushActionAttrs<Self> {
7582 let header_offset = push_nested_header(self.as_rec_mut(), 1u16);
7583 PushActionAttrs {
7584 prev: Some(self),
7585 header_offset: Some(header_offset),
7586 }
7587 }
7588}
7589impl<Prev: Rec> Drop for PushDecTtlAttrs<Prev> {
7590 fn drop(&mut self) {
7591 if let Some(prev) = &mut self.prev {
7592 if let Some(header_offset) = &self.header_offset {
7593 finalize_nested_header(prev.as_rec_mut(), *header_offset);
7594 }
7595 }
7596 }
7597}
7598pub struct PushVxlanExtAttrs<Prev: Rec> {
7599 pub(crate) prev: Option<Prev>,
7600 pub(crate) header_offset: Option<usize>,
7601}
7602impl<Prev: Rec> Rec for PushVxlanExtAttrs<Prev> {
7603 fn as_rec_mut(&mut self) -> &mut Vec<u8> {
7604 self.prev.as_mut().unwrap().as_rec_mut()
7605 }
7606 fn as_rec(&self) -> &Vec<u8> {
7607 self.prev.as_ref().unwrap().as_rec()
7608 }
7609}
7610impl<Prev: Rec> PushVxlanExtAttrs<Prev> {
7611 pub fn new(prev: Prev) -> Self {
7612 Self {
7613 prev: Some(prev),
7614 header_offset: None,
7615 }
7616 }
7617 pub fn end_nested(mut self) -> Prev {
7618 let mut prev = self.prev.take().unwrap();
7619 if let Some(header_offset) = &self.header_offset {
7620 finalize_nested_header(prev.as_rec_mut(), *header_offset);
7621 }
7622 prev
7623 }
7624 pub fn push_gbp(mut self, value: u32) -> Self {
7625 push_header(self.as_rec_mut(), 1u16, 4 as u16);
7626 self.as_rec_mut().extend(value.to_ne_bytes());
7627 self
7628 }
7629}
7630impl<Prev: Rec> Drop for PushVxlanExtAttrs<Prev> {
7631 fn drop(&mut self) {
7632 if let Some(prev) = &mut self.prev {
7633 if let Some(header_offset) = &self.header_offset {
7634 finalize_nested_header(prev.as_rec_mut(), *header_offset);
7635 }
7636 }
7637 }
7638}
7639pub struct PushPsampleAttrs<Prev: Rec> {
7640 pub(crate) prev: Option<Prev>,
7641 pub(crate) header_offset: Option<usize>,
7642}
7643impl<Prev: Rec> Rec for PushPsampleAttrs<Prev> {
7644 fn as_rec_mut(&mut self) -> &mut Vec<u8> {
7645 self.prev.as_mut().unwrap().as_rec_mut()
7646 }
7647 fn as_rec(&self) -> &Vec<u8> {
7648 self.prev.as_ref().unwrap().as_rec()
7649 }
7650}
7651impl<Prev: Rec> PushPsampleAttrs<Prev> {
7652 pub fn new(prev: Prev) -> Self {
7653 Self {
7654 prev: Some(prev),
7655 header_offset: None,
7656 }
7657 }
7658 pub fn end_nested(mut self) -> Prev {
7659 let mut prev = self.prev.take().unwrap();
7660 if let Some(header_offset) = &self.header_offset {
7661 finalize_nested_header(prev.as_rec_mut(), *header_offset);
7662 }
7663 prev
7664 }
7665 pub fn push_group(mut self, value: u32) -> Self {
7666 push_header(self.as_rec_mut(), 1u16, 4 as u16);
7667 self.as_rec_mut().extend(value.to_ne_bytes());
7668 self
7669 }
7670 pub fn push_cookie(mut self, value: &[u8]) -> Self {
7671 push_header(self.as_rec_mut(), 2u16, value.len() as u16);
7672 self.as_rec_mut().extend(value);
7673 self
7674 }
7675}
7676impl<Prev: Rec> Drop for PushPsampleAttrs<Prev> {
7677 fn drop(&mut self) {
7678 if let Some(prev) = &mut self.prev {
7679 if let Some(header_offset) = &self.header_offset {
7680 finalize_nested_header(prev.as_rec_mut(), *header_offset);
7681 }
7682 }
7683 }
7684}
7685pub struct NotifGroup;
7686impl NotifGroup {
7687 pub const OVS_FLOW: &str = "ovs_flow";
7688 pub const OVS_FLOW_CSTR: &CStr = c"ovs_flow";
7689}
7690#[doc = "Get / dump OVS flow configuration and state\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"]
7691#[derive(Debug)]
7692pub struct OpGetDump<'r> {
7693 request: Request<'r>,
7694}
7695impl<'r> OpGetDump<'r> {
7696 pub fn new(mut request: Request<'r>, header: &OvsHeader) -> Self {
7697 Self::write_header(request.buf_mut(), header);
7698 Self {
7699 request: request.set_dump(),
7700 }
7701 }
7702 pub fn encode_request<'buf>(
7703 buf: &'buf mut Vec<u8>,
7704 header: &OvsHeader,
7705 ) -> PushFlowAttrs<&'buf mut Vec<u8>> {
7706 Self::write_header(buf, header);
7707 PushFlowAttrs::new(buf)
7708 }
7709 pub fn encode(&mut self) -> PushFlowAttrs<&mut Vec<u8>> {
7710 PushFlowAttrs::new(self.request.buf_mut())
7711 }
7712 pub fn into_encoder(self) -> PushFlowAttrs<RequestBuf<'r>> {
7713 PushFlowAttrs::new(self.request.buf)
7714 }
7715 pub fn decode_request<'a>(buf: &'a [u8]) -> (OvsHeader, IterableFlowAttrs<'a>) {
7716 let (header, attrs) = buf.split_at(buf.len().min(OvsHeader::len()));
7717 (
7718 OvsHeader::new_from_slice(header).unwrap_or_default(),
7719 IterableFlowAttrs::with_loc(attrs, buf.as_ptr() as usize),
7720 )
7721 }
7722 fn write_header<Prev: Rec>(prev: &mut Prev, header: &OvsHeader) {
7723 prev.as_rec_mut().extend(header.as_slice());
7724 }
7725}
7726impl NetlinkRequest for OpGetDump<'_> {
7727 fn protocol(&self) -> Protocol {
7728 Protocol::Generic("ovs_flow".as_bytes())
7729 }
7730 fn flags(&self) -> u16 {
7731 self.request.flags
7732 }
7733 fn payload(&self) -> &[u8] {
7734 self.request.buf()
7735 }
7736 type ReplyType<'buf> = (OvsHeader, IterableFlowAttrs<'buf>);
7737 fn decode_reply<'buf>(buf: &'buf [u8]) -> Self::ReplyType<'buf> {
7738 Self::decode_request(buf)
7739 }
7740 fn lookup(
7741 buf: &[u8],
7742 offset: usize,
7743 missing_type: Option<u16>,
7744 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
7745 Self::decode_request(buf)
7746 .1
7747 .lookup_attr(offset, missing_type)
7748 }
7749}
7750#[doc = "Get / dump OVS flow configuration and state\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"]
7751#[derive(Debug)]
7752pub struct OpGetDo<'r> {
7753 request: Request<'r>,
7754}
7755impl<'r> OpGetDo<'r> {
7756 pub fn new(mut request: Request<'r>, header: &OvsHeader) -> Self {
7757 Self::write_header(request.buf_mut(), header);
7758 Self { request: request }
7759 }
7760 pub fn encode_request<'buf>(
7761 buf: &'buf mut Vec<u8>,
7762 header: &OvsHeader,
7763 ) -> PushFlowAttrs<&'buf mut Vec<u8>> {
7764 Self::write_header(buf, header);
7765 PushFlowAttrs::new(buf)
7766 }
7767 pub fn encode(&mut self) -> PushFlowAttrs<&mut Vec<u8>> {
7768 PushFlowAttrs::new(self.request.buf_mut())
7769 }
7770 pub fn into_encoder(self) -> PushFlowAttrs<RequestBuf<'r>> {
7771 PushFlowAttrs::new(self.request.buf)
7772 }
7773 pub fn decode_request<'a>(buf: &'a [u8]) -> (OvsHeader, IterableFlowAttrs<'a>) {
7774 let (header, attrs) = buf.split_at(buf.len().min(OvsHeader::len()));
7775 (
7776 OvsHeader::new_from_slice(header).unwrap_or_default(),
7777 IterableFlowAttrs::with_loc(attrs, buf.as_ptr() as usize),
7778 )
7779 }
7780 fn write_header<Prev: Rec>(prev: &mut Prev, header: &OvsHeader) {
7781 prev.as_rec_mut().extend(header.as_slice());
7782 }
7783}
7784impl NetlinkRequest for OpGetDo<'_> {
7785 fn protocol(&self) -> Protocol {
7786 Protocol::Generic("ovs_flow".as_bytes())
7787 }
7788 fn flags(&self) -> u16 {
7789 self.request.flags
7790 }
7791 fn payload(&self) -> &[u8] {
7792 self.request.buf()
7793 }
7794 type ReplyType<'buf> = (OvsHeader, IterableFlowAttrs<'buf>);
7795 fn decode_reply<'buf>(buf: &'buf [u8]) -> Self::ReplyType<'buf> {
7796 Self::decode_request(buf)
7797 }
7798 fn lookup(
7799 buf: &[u8],
7800 offset: usize,
7801 missing_type: Option<u16>,
7802 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
7803 Self::decode_request(buf)
7804 .1
7805 .lookup_attr(offset, missing_type)
7806 }
7807}
7808#[doc = "Create OVS flow configuration in a data path\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"]
7809#[derive(Debug)]
7810pub struct OpNewDo<'r> {
7811 request: Request<'r>,
7812}
7813impl<'r> OpNewDo<'r> {
7814 pub fn new(mut request: Request<'r>, header: &OvsHeader) -> Self {
7815 Self::write_header(request.buf_mut(), header);
7816 Self { request: request }
7817 }
7818 pub fn encode_request<'buf>(
7819 buf: &'buf mut Vec<u8>,
7820 header: &OvsHeader,
7821 ) -> PushFlowAttrs<&'buf mut Vec<u8>> {
7822 Self::write_header(buf, header);
7823 PushFlowAttrs::new(buf)
7824 }
7825 pub fn encode(&mut self) -> PushFlowAttrs<&mut Vec<u8>> {
7826 PushFlowAttrs::new(self.request.buf_mut())
7827 }
7828 pub fn into_encoder(self) -> PushFlowAttrs<RequestBuf<'r>> {
7829 PushFlowAttrs::new(self.request.buf)
7830 }
7831 pub fn decode_request<'a>(buf: &'a [u8]) -> (OvsHeader, IterableFlowAttrs<'a>) {
7832 let (header, attrs) = buf.split_at(buf.len().min(OvsHeader::len()));
7833 (
7834 OvsHeader::new_from_slice(header).unwrap_or_default(),
7835 IterableFlowAttrs::with_loc(attrs, buf.as_ptr() as usize),
7836 )
7837 }
7838 fn write_header<Prev: Rec>(prev: &mut Prev, header: &OvsHeader) {
7839 prev.as_rec_mut().extend(header.as_slice());
7840 }
7841}
7842impl NetlinkRequest for OpNewDo<'_> {
7843 fn protocol(&self) -> Protocol {
7844 Protocol::Generic("ovs_flow".as_bytes())
7845 }
7846 fn flags(&self) -> u16 {
7847 self.request.flags
7848 }
7849 fn payload(&self) -> &[u8] {
7850 self.request.buf()
7851 }
7852 type ReplyType<'buf> = (OvsHeader, IterableFlowAttrs<'buf>);
7853 fn decode_reply<'buf>(buf: &'buf [u8]) -> Self::ReplyType<'buf> {
7854 Self::decode_request(buf)
7855 }
7856 fn lookup(
7857 buf: &[u8],
7858 offset: usize,
7859 missing_type: Option<u16>,
7860 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
7861 Self::decode_request(buf)
7862 .1
7863 .lookup_attr(offset, missing_type)
7864 }
7865}
7866use crate::traits::LookupFn;
7867use crate::utils::RequestBuf;
7868#[derive(Debug)]
7869pub struct Request<'buf> {
7870 buf: RequestBuf<'buf>,
7871 flags: u16,
7872 writeback: Option<&'buf mut Option<RequestInfo>>,
7873}
7874#[allow(unused)]
7875#[derive(Debug, Clone)]
7876pub struct RequestInfo {
7877 protocol: Protocol,
7878 flags: u16,
7879 name: &'static str,
7880 lookup: LookupFn,
7881}
7882impl Request<'static> {
7883 pub fn new() -> Self {
7884 Self::new_from_buf(Vec::new())
7885 }
7886 pub fn new_from_buf(buf: Vec<u8>) -> Self {
7887 Self {
7888 flags: 0,
7889 buf: RequestBuf::Own(buf),
7890 writeback: None,
7891 }
7892 }
7893 pub fn into_buf(self) -> Vec<u8> {
7894 match self.buf {
7895 RequestBuf::Own(buf) => buf,
7896 _ => unreachable!(),
7897 }
7898 }
7899}
7900impl<'buf> Request<'buf> {
7901 pub fn new_with_buf(buf: &'buf mut Vec<u8>) -> Self {
7902 buf.clear();
7903 Self::new_extend(buf)
7904 }
7905 pub fn new_extend(buf: &'buf mut Vec<u8>) -> Self {
7906 Self {
7907 flags: 0,
7908 buf: RequestBuf::Ref(buf),
7909 writeback: None,
7910 }
7911 }
7912 fn do_writeback(&mut self, protocol: Protocol, name: &'static str, lookup: LookupFn) {
7913 let Some(writeback) = &mut self.writeback else {
7914 return;
7915 };
7916 **writeback = Some(RequestInfo {
7917 protocol,
7918 flags: self.flags,
7919 name,
7920 lookup,
7921 })
7922 }
7923 pub fn buf(&self) -> &Vec<u8> {
7924 self.buf.buf()
7925 }
7926 pub fn buf_mut(&mut self) -> &mut Vec<u8> {
7927 self.buf.buf_mut()
7928 }
7929 #[doc = "Set `NLM_F_CREATE` flag"]
7930 pub fn set_create(mut self) -> Self {
7931 self.flags |= consts::NLM_F_CREATE as u16;
7932 self
7933 }
7934 #[doc = "Set `NLM_F_EXCL` flag"]
7935 pub fn set_excl(mut self) -> Self {
7936 self.flags |= consts::NLM_F_EXCL as u16;
7937 self
7938 }
7939 #[doc = "Set `NLM_F_REPLACE` flag"]
7940 pub fn set_replace(mut self) -> Self {
7941 self.flags |= consts::NLM_F_REPLACE as u16;
7942 self
7943 }
7944 #[doc = "Set `NLM_F_CREATE` and `NLM_F_REPLACE` flag"]
7945 pub fn set_change(self) -> Self {
7946 self.set_create().set_replace()
7947 }
7948 #[doc = "Set `NLM_F_APPEND` flag"]
7949 pub fn set_append(mut self) -> Self {
7950 self.flags |= consts::NLM_F_APPEND as u16;
7951 self
7952 }
7953 #[doc = "Set `self.flags |= flags`"]
7954 pub fn set_flags(mut self, flags: u16) -> Self {
7955 self.flags |= flags;
7956 self
7957 }
7958 #[doc = "Set `self.flags ^= self.flags & flags`"]
7959 pub fn unset_flags(mut self, flags: u16) -> Self {
7960 self.flags ^= self.flags & flags;
7961 self
7962 }
7963 #[doc = "Set `NLM_F_DUMP` flag"]
7964 fn set_dump(mut self) -> Self {
7965 self.flags |= consts::NLM_F_DUMP as u16;
7966 self
7967 }
7968 #[doc = "Get / dump OVS flow configuration and state\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"]
7969 pub fn op_get_dump(self, header: &OvsHeader) -> OpGetDump<'buf> {
7970 let mut res = OpGetDump::new(self, header);
7971 res.request
7972 .do_writeback(res.protocol(), "op-get-dump", OpGetDump::lookup);
7973 res
7974 }
7975 #[doc = "Get / dump OVS flow configuration and state\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"]
7976 pub fn op_get_do(self, header: &OvsHeader) -> OpGetDo<'buf> {
7977 let mut res = OpGetDo::new(self, header);
7978 res.request
7979 .do_writeback(res.protocol(), "op-get-do", OpGetDo::lookup);
7980 res
7981 }
7982 #[doc = "Create OVS flow configuration in a data path\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"]
7983 pub fn op_new_do(self, header: &OvsHeader) -> OpNewDo<'buf> {
7984 let mut res = OpNewDo::new(self, header);
7985 res.request
7986 .do_writeback(res.protocol(), "op-new-do", OpNewDo::lookup);
7987 res
7988 }
7989}
7990#[cfg(test)]
7991mod generated_tests {
7992 use super::*;
7993 #[test]
7994 fn tests() {
7995 let _ = IterableFlowAttrs::get_actions;
7996 let _ = IterableFlowAttrs::get_key;
7997 let _ = IterableFlowAttrs::get_mask;
7998 let _ = IterableFlowAttrs::get_stats;
7999 let _ = IterableFlowAttrs::get_ufid;
8000 let _ = PushFlowAttrs::<&mut Vec<u8>>::nested_actions;
8001 let _ = PushFlowAttrs::<&mut Vec<u8>>::nested_key;
8002 let _ = PushFlowAttrs::<&mut Vec<u8>>::nested_mask;
8003 let _ = PushFlowAttrs::<&mut Vec<u8>>::push_ufid;
8004 let _ = PushFlowAttrs::<&mut Vec<u8>>::push_ufid_flags;
8005 }
8006}