netlink_packet_route/link/
ext_mask.rs

1// SPDX-License-Identifier: MIT
2
3const RTEXT_FILTER_VF: u32 = 1 << 0;
4const RTEXT_FILTER_BRVLAN: u32 = 1 << 1;
5const RTEXT_FILTER_BRVLAN_COMPRESSED: u32 = 1 << 2;
6const RTEXT_FILTER_SKIP_STATS: u32 = 1 << 3;
7const RTEXT_FILTER_MRP: u32 = 1 << 4;
8const RTEXT_FILTER_CFM_CONFIG: u32 = 1 << 5;
9const RTEXT_FILTER_CFM_STATUS: u32 = 1 << 6;
10const RTEXT_FILTER_MST: u32 = 1 << 7;
11
12#[derive(Debug, PartialEq, Eq, Clone, Default)]
13pub(crate) struct VecLinkExtentMask(pub(crate) Vec<LinkExtentMask>);
14
15#[derive(Debug, PartialEq, Eq, Clone, Copy)]
16#[non_exhaustive]
17#[repr(u32)]
18pub enum LinkExtentMask {
19    Vf,
20    Brvlan,
21    BrvlanCompressed,
22    SkipStats,
23    Mrp,
24    CfmConfig,
25    CfmStatus,
26    Mst,
27    Other(u32),
28}
29
30impl From<u32> for LinkExtentMask {
31    fn from(d: u32) -> Self {
32        match d {
33            RTEXT_FILTER_VF => Self::Vf,
34            RTEXT_FILTER_BRVLAN => Self::Brvlan,
35            RTEXT_FILTER_BRVLAN_COMPRESSED => Self::BrvlanCompressed,
36            RTEXT_FILTER_SKIP_STATS => Self::SkipStats,
37            RTEXT_FILTER_MRP => Self::Mrp,
38            RTEXT_FILTER_CFM_CONFIG => Self::CfmConfig,
39            RTEXT_FILTER_CFM_STATUS => Self::CfmStatus,
40            RTEXT_FILTER_MST => Self::Mst,
41            _ => Self::Other(d),
42        }
43    }
44}
45
46impl From<LinkExtentMask> for u32 {
47    fn from(v: LinkExtentMask) -> u32 {
48        match v {
49            LinkExtentMask::Vf => RTEXT_FILTER_VF,
50            LinkExtentMask::Brvlan => RTEXT_FILTER_BRVLAN,
51            LinkExtentMask::BrvlanCompressed => RTEXT_FILTER_BRVLAN_COMPRESSED,
52            LinkExtentMask::SkipStats => RTEXT_FILTER_SKIP_STATS,
53            LinkExtentMask::Mrp => RTEXT_FILTER_MRP,
54            LinkExtentMask::CfmConfig => RTEXT_FILTER_CFM_CONFIG,
55            LinkExtentMask::CfmStatus => RTEXT_FILTER_CFM_STATUS,
56            LinkExtentMask::Mst => RTEXT_FILTER_MST,
57            LinkExtentMask::Other(i) => i,
58        }
59    }
60}
61
62const ALL_LINK_FLAGS: [LinkExtentMask; 8] = [
63    LinkExtentMask::Vf,
64    LinkExtentMask::Brvlan,
65    LinkExtentMask::BrvlanCompressed,
66    LinkExtentMask::SkipStats,
67    LinkExtentMask::Mrp,
68    LinkExtentMask::CfmConfig,
69    LinkExtentMask::CfmStatus,
70    LinkExtentMask::Mst,
71];
72
73impl From<u32> for VecLinkExtentMask {
74    fn from(d: u32) -> Self {
75        let mut got: u32 = 0;
76        let mut ret = Vec::new();
77        for flag in ALL_LINK_FLAGS {
78            if (d & u32::from(flag)) > 0 {
79                ret.push(flag);
80                got += u32::from(flag);
81            }
82        }
83        if got != d {
84            ret.push(LinkExtentMask::Other(d - got));
85        }
86        Self(ret)
87    }
88}
89
90impl From<&VecLinkExtentMask> for u32 {
91    fn from(v: &VecLinkExtentMask) -> u32 {
92        let mut d: u32 = 0;
93        for flag in &v.0 {
94            d += u32::from(*flag);
95        }
96        d
97    }
98}