netlink_packet_route/link/link_info/
ipvlan.rs1use netlink_packet_core::{
4 emit_u16, parse_u16, DecodeError, DefaultNla, ErrorContext, Nla, NlaBuffer,
5 Parseable,
6};
7
8const IFLA_IPVLAN_MODE: u16 = 1;
9const IFLA_IPVLAN_FLAGS: u16 = 2;
10
11#[derive(Debug, PartialEq, Eq, Clone)]
12#[non_exhaustive]
13pub enum InfoIpVlan {
14 Mode(IpVlanMode),
15 Flags(IpVlanFlags),
16 Other(DefaultNla),
17}
18
19impl Nla for InfoIpVlan {
20 fn value_len(&self) -> usize {
21 use self::InfoIpVlan::*;
22 match self {
23 Mode(_) | Flags(_) => 2,
24 Other(nla) => nla.value_len(),
25 }
26 }
27
28 fn emit_value(&self, buffer: &mut [u8]) {
29 use self::InfoIpVlan::*;
30 match self {
31 Mode(value) => emit_u16(buffer, (*value).into()).unwrap(),
32 Flags(f) => emit_u16(buffer, f.bits()).unwrap(),
33 Other(nla) => nla.emit_value(buffer),
34 }
35 }
36
37 fn kind(&self) -> u16 {
38 use self::InfoIpVlan::*;
39 match self {
40 Mode(_) => IFLA_IPVLAN_MODE,
41 Flags(_) => IFLA_IPVLAN_FLAGS,
42 Other(nla) => nla.kind(),
43 }
44 }
45}
46
47impl<'a, T: AsRef<[u8]> + ?Sized> Parseable<NlaBuffer<&'a T>> for InfoIpVlan {
48 fn parse(buf: &NlaBuffer<&'a T>) -> Result<Self, DecodeError> {
49 use self::InfoIpVlan::*;
50 let payload = buf.value();
51 Ok(match buf.kind() {
52 IFLA_IPVLAN_MODE => Mode(
53 parse_u16(payload)
54 .context("invalid IFLA_IPVLAN_MODE value")?
55 .into(),
56 ),
57 IFLA_IPVLAN_FLAGS => Self::Flags(IpVlanFlags::from_bits_retain(
58 parse_u16(payload)
59 .context("failed to parse IFLA_IPVLAN_FLAGS")?,
60 )),
61 kind => Other(DefaultNla::parse(buf).context(format!(
62 "unknown NLA type {kind} for IFLA_INFO_DATA(ipvlan)"
63 ))?),
64 })
65 }
66}
67
68#[derive(Debug, PartialEq, Eq, Clone)]
69#[non_exhaustive]
70pub enum InfoIpVtap {
71 Mode(IpVtapMode),
72 Flags(IpVtapFlags),
73 Other(DefaultNla),
74}
75
76impl Nla for InfoIpVtap {
77 fn value_len(&self) -> usize {
78 use self::InfoIpVtap::*;
79 match self {
80 Mode(_) | Flags(_) => 2,
81 Other(nla) => nla.value_len(),
82 }
83 }
84
85 fn emit_value(&self, buffer: &mut [u8]) {
86 use self::InfoIpVtap::*;
87 match self {
88 Mode(value) => emit_u16(buffer, (*value).into()).unwrap(),
89 Flags(f) => emit_u16(buffer, f.bits()).unwrap(),
90 Other(nla) => nla.emit_value(buffer),
91 }
92 }
93
94 fn kind(&self) -> u16 {
95 use self::InfoIpVtap::*;
96 match self {
97 Mode(_) => IFLA_IPVLAN_MODE,
98 Flags(_) => IFLA_IPVLAN_FLAGS,
99 Other(nla) => nla.kind(),
100 }
101 }
102}
103
104impl<'a, T: AsRef<[u8]> + ?Sized> Parseable<NlaBuffer<&'a T>> for InfoIpVtap {
105 fn parse(buf: &NlaBuffer<&'a T>) -> Result<Self, DecodeError> {
106 use self::InfoIpVtap::*;
107 let payload = buf.value();
108 Ok(match buf.kind() {
109 IFLA_IPVLAN_MODE => Mode(
110 parse_u16(payload)
111 .context("invalid IFLA_IPVLAN_MODE value")?
112 .into(),
113 ),
114 IFLA_IPVLAN_FLAGS => Self::Flags(IpVtapFlags::from_bits_retain(
115 parse_u16(payload)
116 .context("failed to parse IFLA_IPVLAN_FLAGS")?,
117 )),
118 kind => Other(DefaultNla::parse(buf).context(format!(
119 "unknown NLA type {kind} for IFLA_INFO_DATA(ipvlan)"
120 ))?),
121 })
122 }
123}
124
125const IPVLAN_MODE_L2: u16 = 0;
126const IPVLAN_MODE_L3: u16 = 1;
127const IPVLAN_MODE_L3S: u16 = 2;
128
129#[derive(Debug, PartialEq, Eq, Clone, Copy)]
130#[non_exhaustive]
131pub enum IpVlanMode {
132 L2,
133 L3,
134 L3S,
135 Other(u16),
136}
137
138pub type IpVtapMode = IpVlanMode;
139
140impl From<u16> for IpVlanMode {
141 fn from(d: u16) -> Self {
142 match d {
143 IPVLAN_MODE_L2 => Self::L2,
144 IPVLAN_MODE_L3 => Self::L3,
145 IPVLAN_MODE_L3S => Self::L3S,
146 _ => {
147 log::warn!("Unknown IP VLAN mode {d}");
148 Self::Other(d)
149 }
150 }
151 }
152}
153
154impl From<IpVlanMode> for u16 {
155 fn from(v: IpVlanMode) -> u16 {
156 match v {
157 IpVlanMode::L2 => IPVLAN_MODE_L2,
158 IpVlanMode::L3 => IPVLAN_MODE_L3,
159 IpVlanMode::L3S => IPVLAN_MODE_L3S,
160 IpVlanMode::Other(d) => d,
161 }
162 }
163}
164
165const IPVLAN_F_PRIVATE: u16 = 0x01;
166const IPVLAN_F_VEPA: u16 = 0x02;
167
168bitflags! {
169 #[non_exhaustive]
170 #[derive(Debug, Clone, Copy, Eq, PartialEq)]
171 pub struct IpVlanFlags: u16 {
172 const Private = IPVLAN_F_PRIVATE;
173 const Vepa = IPVLAN_F_VEPA;
174 const _ = !0;
175 }
176}
177
178impl Default for IpVlanFlags {
179 fn default() -> Self {
180 Self::empty()
181 }
182}
183
184pub type IpVtapFlags = IpVlanFlags;