Skip to main content

netlink_bindings/ovs_flow/
mod.rs

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