Skip to content

Commit a8d125c

Browse files
xujunjie-covercathay4t
authored andcommitted
link: ipvtap: support ipvtap mod. ipvtap is alias to ipvlan mode.
Signed-off-by: xujunjie-cover <[email protected]>
1 parent 396d4b0 commit a8d125c

File tree

7 files changed

+138
-9
lines changed

7 files changed

+138
-9
lines changed

src/link/link_info/info_data.rs

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,9 @@ use netlink_packet_utils::{
99

1010
use super::super::{
1111
InfoBond, InfoBridge, InfoGreTap, InfoGreTap6, InfoGreTun, InfoGreTun6,
12-
InfoGtp, InfoHsr, InfoIpVlan, InfoIpoib, InfoKind, InfoMacSec, InfoMacVlan,
13-
InfoMacVtap, InfoSitTun, InfoTun, InfoVeth, InfoVlan, InfoVrf, InfoVti,
14-
InfoVxlan, InfoXfrm,
12+
InfoGtp, InfoHsr, InfoIpVlan, InfoIpVtap, InfoIpoib, InfoKind, InfoMacSec,
13+
InfoMacVlan, InfoMacVtap, InfoSitTun, InfoTun, InfoVeth, InfoVlan, InfoVrf,
14+
InfoVti, InfoVxlan, InfoXfrm,
1515
};
1616

1717
const IFLA_INFO_DATA: u16 = 2;
@@ -26,6 +26,7 @@ pub enum InfoData {
2626
Vxlan(Vec<InfoVxlan>),
2727
Bond(Vec<InfoBond>),
2828
IpVlan(Vec<InfoIpVlan>),
29+
IpVtap(Vec<InfoIpVtap>),
2930
MacVlan(Vec<InfoMacVlan>),
3031
MacVtap(Vec<InfoMacVtap>),
3132
GreTap(Vec<InfoGreTap>),
@@ -51,6 +52,7 @@ impl Nla for InfoData {
5152
Self::Vlan(nlas) => nlas.as_slice().buffer_len(),
5253
Self::Veth(msg) => msg.buffer_len(),
5354
Self::IpVlan(nlas) => nlas.as_slice().buffer_len(),
55+
Self::IpVtap(nlas) => nlas.as_slice().buffer_len(),
5456
Self::Ipoib(nlas) => nlas.as_slice().buffer_len(),
5557
Self::MacVlan(nlas) => nlas.as_slice().buffer_len(),
5658
Self::MacVtap(nlas) => nlas.as_slice().buffer_len(),
@@ -78,6 +80,7 @@ impl Nla for InfoData {
7880
Self::Vlan(nlas) => nlas.as_slice().emit(buffer),
7981
Self::Veth(msg) => msg.emit(buffer),
8082
Self::IpVlan(nlas) => nlas.as_slice().emit(buffer),
83+
Self::IpVtap(nlas) => nlas.as_slice().emit(buffer),
8184
Self::Ipoib(nlas) => nlas.as_slice().emit(buffer),
8285
Self::MacVlan(nlas) => nlas.as_slice().emit(buffer),
8386
Self::MacVtap(nlas) => nlas.as_slice().emit(buffer),
@@ -182,6 +185,17 @@ impl InfoData {
182185
}
183186
InfoData::IpVlan(v)
184187
}
188+
InfoKind::IpVtap => {
189+
let mut v = Vec::new();
190+
for nla in NlasIterator::new(payload) {
191+
let nla = &nla.context(format!(
192+
"invalid IFLA_INFO_DATA for {kind} {payload:?}"
193+
))?;
194+
let parsed = InfoIpVtap::parse(nla)?;
195+
v.push(parsed);
196+
}
197+
InfoData::IpVtap(v)
198+
}
185199
InfoKind::MacVlan => {
186200
let mut v = Vec::new();
187201
for nla in NlasIterator::new(payload) {

src/link/link_info/infos.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ const VETH: &str = "veth";
2525
const VXLAN: &str = "vxlan";
2626
const BOND: &str = "bond";
2727
const IPVLAN: &str = "ipvlan";
28+
const IPVTAP: &str = "ipvtap";
2829
const MACVLAN: &str = "macvlan";
2930
const MACVTAP: &str = "macvtap";
3031
const GRETAP: &str = "gretap";
@@ -182,6 +183,7 @@ pub enum InfoKind {
182183
Vxlan,
183184
Bond,
184185
IpVlan,
186+
IpVtap,
185187
MacVlan,
186188
MacVtap,
187189
GreTap,
@@ -217,6 +219,7 @@ impl std::fmt::Display for InfoKind {
217219
Self::Vxlan => VXLAN,
218220
Self::Bond => BOND,
219221
Self::IpVlan => IPVLAN,
222+
Self::IpVtap => IPVTAP,
220223
Self::MacVlan => MACVLAN,
221224
Self::MacVtap => MACVTAP,
222225
Self::GreTap => GRETAP,
@@ -252,6 +255,7 @@ impl Nla for InfoKind {
252255
Self::Vxlan => VXLAN.len(),
253256
Self::Bond => BOND.len(),
254257
Self::IpVlan => IPVLAN.len(),
258+
Self::IpVtap => IPVTAP.len(),
255259
Self::MacVlan => MACVLAN.len(),
256260
Self::MacVtap => MACVTAP.len(),
257261
Self::GreTap => GRETAP.len(),
@@ -307,6 +311,7 @@ impl<'a, T: AsRef<[u8]> + ?Sized> Parseable<NlaBuffer<&'a T>> for InfoKind {
307311
VXLAN => Self::Vxlan,
308312
BOND => Self::Bond,
309313
IPVLAN => Self::IpVlan,
314+
IPVTAP => Self::IpVtap,
310315
MACVLAN => Self::MacVlan,
311316
MACVTAP => Self::MacVtap,
312317
GRETAP => Self::GreTap,

src/link/link_info/ipvlan.rs

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,63 @@ impl<'a, T: AsRef<[u8]> + ?Sized> Parseable<NlaBuffer<&'a T>> for InfoIpVlan {
6969
}
7070
}
7171

72+
#[derive(Debug, PartialEq, Eq, Clone)]
73+
#[non_exhaustive]
74+
pub enum InfoIpVtap {
75+
Mode(IpVtapMode),
76+
Flags(u16),
77+
Other(DefaultNla),
78+
}
79+
80+
impl Nla for InfoIpVtap {
81+
fn value_len(&self) -> usize {
82+
use self::InfoIpVtap::*;
83+
match self {
84+
Mode(_) | Flags(_) => 2,
85+
Other(nla) => nla.value_len(),
86+
}
87+
}
88+
89+
fn emit_value(&self, buffer: &mut [u8]) {
90+
use self::InfoIpVtap::*;
91+
match self {
92+
Mode(value) => NativeEndian::write_u16(buffer, (*value).into()),
93+
Flags(value) => NativeEndian::write_u16(buffer, *value),
94+
Other(nla) => nla.emit_value(buffer),
95+
}
96+
}
97+
98+
fn kind(&self) -> u16 {
99+
use self::InfoIpVtap::*;
100+
match self {
101+
Mode(_) => IFLA_IPVLAN_MODE,
102+
Flags(_) => IFLA_IPVLAN_FLAGS,
103+
Other(nla) => nla.kind(),
104+
}
105+
}
106+
}
107+
108+
impl<'a, T: AsRef<[u8]> + ?Sized> Parseable<NlaBuffer<&'a T>> for InfoIpVtap {
109+
fn parse(buf: &NlaBuffer<&'a T>) -> Result<Self, DecodeError> {
110+
use self::InfoIpVtap::*;
111+
let payload = buf.value();
112+
Ok(match buf.kind() {
113+
IFLA_IPVLAN_MODE => Mode(
114+
parse_u16(payload)
115+
.context("invalid IFLA_IPVLAN_MODE value")?
116+
.into(),
117+
),
118+
IFLA_IPVLAN_FLAGS => Flags(
119+
parse_u16(payload)
120+
.context("invalid IFLA_IPVLAN_FLAGS value")?,
121+
),
122+
kind => Other(DefaultNla::parse(buf).context(format!(
123+
"unknown NLA type {kind} for IFLA_INFO_DATA(ipvlan)"
124+
))?),
125+
})
126+
}
127+
}
128+
72129
const IPVLAN_MODE_L2: u16 = 0;
73130
const IPVLAN_MODE_L3: u16 = 1;
74131
const IPVLAN_MODE_L3S: u16 = 2;
@@ -82,6 +139,8 @@ pub enum IpVlanMode {
82139
Other(u16),
83140
}
84141

142+
pub type IpVtapMode = IpVlanMode;
143+
85144
impl From<u16> for IpVlanMode {
86145
fn from(d: u16) -> Self {
87146
match d {

src/link/link_info/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ pub use self::info_data::InfoData;
4545
pub use self::info_port::{InfoPortData, InfoPortKind};
4646
pub use self::infos::{InfoKind, LinkInfo};
4747
pub use self::ipoib::InfoIpoib;
48-
pub use self::ipvlan::{InfoIpVlan, IpVlanMode};
48+
pub use self::ipvlan::{InfoIpVlan, InfoIpVtap, IpVlanMode, IpVtapMode};
4949
pub use self::mac_vlan::{InfoMacVlan, InfoMacVtap, MacVlanMode, MacVtapMode};
5050
pub use self::macsec::{
5151
InfoMacSec, MacSecCipherId, MacSecOffload, MacSecValidate,

src/link/mod.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -42,11 +42,11 @@ pub use self::link_info::{
4242
BridgePortMulticastRouter, BridgePortState, BridgeQuerierState,
4343
HsrProtocol, InfoBond, InfoBondPort, InfoBridge, InfoBridgePort, InfoData,
4444
InfoGreTap, InfoGreTap6, InfoGreTun, InfoGreTun6, InfoGtp, InfoHsr,
45-
InfoIpVlan, InfoIpoib, InfoKind, InfoMacSec, InfoMacVlan, InfoMacVtap,
46-
InfoPortData, InfoPortKind, InfoSitTun, InfoTun, InfoVeth, InfoVlan,
47-
InfoVrf, InfoVti, InfoVxlan, InfoXfrm, IpVlanMode, LinkInfo, LinkXstats,
48-
MacSecCipherId, MacSecOffload, MacSecValidate, MacVlanMode, MacVtapMode,
49-
MiiStatus, VlanQosMapping,
45+
InfoIpVlan, InfoIpVtap, InfoIpoib, InfoKind, InfoMacSec, InfoMacVlan,
46+
InfoMacVtap, InfoPortData, InfoPortKind, InfoSitTun, InfoTun, InfoVeth,
47+
InfoVlan, InfoVrf, InfoVti, InfoVxlan, InfoXfrm, IpVlanMode, IpVtapMode,
48+
LinkInfo, LinkXstats, MacSecCipherId, MacSecOffload, MacSecValidate,
49+
MacVlanMode, MacVtapMode, MiiStatus, VlanQosMapping,
5050
};
5151
pub use self::link_layer_type::LinkLayerType;
5252
pub use self::link_state::State;

src/link/tests/ipvtap.rs

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
// SPDX-License-Identifier: MIT
2+
3+
use netlink_packet_utils::{Emitable, Parseable};
4+
5+
use crate::link::link_flag::LinkFlags;
6+
use crate::link::{
7+
InfoData, InfoIpVtap, InfoKind, IpVtapMode, LinkAttribute, LinkHeader,
8+
LinkInfo, LinkLayerType, LinkMessage, LinkMessageBuffer,
9+
};
10+
use crate::AddressFamily;
11+
12+
#[test]
13+
fn test_ipvtap_link_info() {
14+
let raw: Vec<u8> = vec![
15+
0x00, 0x00, 0x01, 0x00, 0x12, 0x00, 0x00, 0x00, 0x02, 0x10, 0x00, 0x00,
16+
0x00, 0x00, 0x00, 0x00, 0x24, 0x00, 0x12, 0x00, 0x0b, 0x00, 0x01, 0x00,
17+
0x69, 0x70, 0x76, 0x74, 0x61, 0x70, 0x00, 0x00, 0x14, 0x00, 0x02, 0x00,
18+
0x06, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x02, 0x00,
19+
0x02, 0x00, 0x00, 0x00,
20+
];
21+
22+
let expected = LinkMessage {
23+
header: LinkHeader {
24+
interface_family: AddressFamily::Unspec,
25+
index: 18,
26+
link_layer_type: LinkLayerType::Ether,
27+
flags: LinkFlags::Broadcast | LinkFlags::Multicast,
28+
change_mask: LinkFlags::empty(),
29+
},
30+
attributes: vec![LinkAttribute::LinkInfo(vec![
31+
LinkInfo::Kind(InfoKind::IpVtap),
32+
LinkInfo::Data(InfoData::IpVtap(vec![
33+
InfoIpVtap::Mode(IpVtapMode::L2),
34+
InfoIpVtap::Flags(2),
35+
])),
36+
])],
37+
};
38+
39+
assert_eq!(
40+
expected,
41+
LinkMessage::parse(&LinkMessageBuffer::new(&raw)).unwrap()
42+
);
43+
44+
let mut buf = vec![0; expected.buffer_len()];
45+
46+
expected.emit(&mut buf);
47+
48+
assert_eq!(buf, raw);
49+
}

src/link/tests/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ mod hsr;
99
#[cfg(test)]
1010
mod ipvlan;
1111
#[cfg(test)]
12+
mod ipvtap;
13+
#[cfg(test)]
1214
mod loopback;
1315
#[cfg(test)]
1416
mod macsec;

0 commit comments

Comments
 (0)