Skip to main content

netlink_bindings/ovs_flow/
mod.rs

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}