Skip to content

Commit

Permalink
link: ipvtap: support ipvtap mod. ipvtap is alias to ipvlan mode.
Browse files Browse the repository at this point in the history
Signed-off-by: xujunjie-cover <[email protected]>
  • Loading branch information
xujunjie-cover authored and cathay4t committed Mar 31, 2024
1 parent 396d4b0 commit a8d125c
Show file tree
Hide file tree
Showing 7 changed files with 138 additions and 9 deletions.
20 changes: 17 additions & 3 deletions src/link/link_info/info_data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ use netlink_packet_utils::{

use super::super::{
InfoBond, InfoBridge, InfoGreTap, InfoGreTap6, InfoGreTun, InfoGreTun6,
InfoGtp, InfoHsr, InfoIpVlan, InfoIpoib, InfoKind, InfoMacSec, InfoMacVlan,
InfoMacVtap, InfoSitTun, InfoTun, InfoVeth, InfoVlan, InfoVrf, InfoVti,
InfoVxlan, InfoXfrm,
InfoGtp, InfoHsr, InfoIpVlan, InfoIpVtap, InfoIpoib, InfoKind, InfoMacSec,
InfoMacVlan, InfoMacVtap, InfoSitTun, InfoTun, InfoVeth, InfoVlan, InfoVrf,
InfoVti, InfoVxlan, InfoXfrm,
};

const IFLA_INFO_DATA: u16 = 2;
Expand All @@ -26,6 +26,7 @@ pub enum InfoData {
Vxlan(Vec<InfoVxlan>),
Bond(Vec<InfoBond>),
IpVlan(Vec<InfoIpVlan>),
IpVtap(Vec<InfoIpVtap>),
MacVlan(Vec<InfoMacVlan>),
MacVtap(Vec<InfoMacVtap>),
GreTap(Vec<InfoGreTap>),
Expand All @@ -51,6 +52,7 @@ impl Nla for InfoData {
Self::Vlan(nlas) => nlas.as_slice().buffer_len(),
Self::Veth(msg) => msg.buffer_len(),
Self::IpVlan(nlas) => nlas.as_slice().buffer_len(),
Self::IpVtap(nlas) => nlas.as_slice().buffer_len(),
Self::Ipoib(nlas) => nlas.as_slice().buffer_len(),
Self::MacVlan(nlas) => nlas.as_slice().buffer_len(),
Self::MacVtap(nlas) => nlas.as_slice().buffer_len(),
Expand Down Expand Up @@ -78,6 +80,7 @@ impl Nla for InfoData {
Self::Vlan(nlas) => nlas.as_slice().emit(buffer),
Self::Veth(msg) => msg.emit(buffer),
Self::IpVlan(nlas) => nlas.as_slice().emit(buffer),
Self::IpVtap(nlas) => nlas.as_slice().emit(buffer),
Self::Ipoib(nlas) => nlas.as_slice().emit(buffer),
Self::MacVlan(nlas) => nlas.as_slice().emit(buffer),
Self::MacVtap(nlas) => nlas.as_slice().emit(buffer),
Expand Down Expand Up @@ -182,6 +185,17 @@ impl InfoData {
}
InfoData::IpVlan(v)
}
InfoKind::IpVtap => {
let mut v = Vec::new();
for nla in NlasIterator::new(payload) {
let nla = &nla.context(format!(
"invalid IFLA_INFO_DATA for {kind} {payload:?}"
))?;
let parsed = InfoIpVtap::parse(nla)?;
v.push(parsed);
}
InfoData::IpVtap(v)
}
InfoKind::MacVlan => {
let mut v = Vec::new();
for nla in NlasIterator::new(payload) {
Expand Down
5 changes: 5 additions & 0 deletions src/link/link_info/infos.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ const VETH: &str = "veth";
const VXLAN: &str = "vxlan";
const BOND: &str = "bond";
const IPVLAN: &str = "ipvlan";
const IPVTAP: &str = "ipvtap";
const MACVLAN: &str = "macvlan";
const MACVTAP: &str = "macvtap";
const GRETAP: &str = "gretap";
Expand Down Expand Up @@ -182,6 +183,7 @@ pub enum InfoKind {
Vxlan,
Bond,
IpVlan,
IpVtap,
MacVlan,
MacVtap,
GreTap,
Expand Down Expand Up @@ -217,6 +219,7 @@ impl std::fmt::Display for InfoKind {
Self::Vxlan => VXLAN,
Self::Bond => BOND,
Self::IpVlan => IPVLAN,
Self::IpVtap => IPVTAP,
Self::MacVlan => MACVLAN,
Self::MacVtap => MACVTAP,
Self::GreTap => GRETAP,
Expand Down Expand Up @@ -252,6 +255,7 @@ impl Nla for InfoKind {
Self::Vxlan => VXLAN.len(),
Self::Bond => BOND.len(),
Self::IpVlan => IPVLAN.len(),
Self::IpVtap => IPVTAP.len(),
Self::MacVlan => MACVLAN.len(),
Self::MacVtap => MACVTAP.len(),
Self::GreTap => GRETAP.len(),
Expand Down Expand Up @@ -307,6 +311,7 @@ impl<'a, T: AsRef<[u8]> + ?Sized> Parseable<NlaBuffer<&'a T>> for InfoKind {
VXLAN => Self::Vxlan,
BOND => Self::Bond,
IPVLAN => Self::IpVlan,
IPVTAP => Self::IpVtap,
MACVLAN => Self::MacVlan,
MACVTAP => Self::MacVtap,
GRETAP => Self::GreTap,
Expand Down
59 changes: 59 additions & 0 deletions src/link/link_info/ipvlan.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,63 @@ impl<'a, T: AsRef<[u8]> + ?Sized> Parseable<NlaBuffer<&'a T>> for InfoIpVlan {
}
}

#[derive(Debug, PartialEq, Eq, Clone)]
#[non_exhaustive]
pub enum InfoIpVtap {
Mode(IpVtapMode),
Flags(u16),
Other(DefaultNla),
}

impl Nla for InfoIpVtap {
fn value_len(&self) -> usize {
use self::InfoIpVtap::*;
match self {
Mode(_) | Flags(_) => 2,
Other(nla) => nla.value_len(),
}
}

fn emit_value(&self, buffer: &mut [u8]) {
use self::InfoIpVtap::*;
match self {
Mode(value) => NativeEndian::write_u16(buffer, (*value).into()),
Flags(value) => NativeEndian::write_u16(buffer, *value),
Other(nla) => nla.emit_value(buffer),
}
}

fn kind(&self) -> u16 {
use self::InfoIpVtap::*;
match self {
Mode(_) => IFLA_IPVLAN_MODE,
Flags(_) => IFLA_IPVLAN_FLAGS,
Other(nla) => nla.kind(),
}
}
}

impl<'a, T: AsRef<[u8]> + ?Sized> Parseable<NlaBuffer<&'a T>> for InfoIpVtap {
fn parse(buf: &NlaBuffer<&'a T>) -> Result<Self, DecodeError> {
use self::InfoIpVtap::*;
let payload = buf.value();
Ok(match buf.kind() {
IFLA_IPVLAN_MODE => Mode(
parse_u16(payload)
.context("invalid IFLA_IPVLAN_MODE value")?
.into(),
),
IFLA_IPVLAN_FLAGS => Flags(
parse_u16(payload)
.context("invalid IFLA_IPVLAN_FLAGS value")?,
),
kind => Other(DefaultNla::parse(buf).context(format!(
"unknown NLA type {kind} for IFLA_INFO_DATA(ipvlan)"
))?),
})
}
}

const IPVLAN_MODE_L2: u16 = 0;
const IPVLAN_MODE_L3: u16 = 1;
const IPVLAN_MODE_L3S: u16 = 2;
Expand All @@ -82,6 +139,8 @@ pub enum IpVlanMode {
Other(u16),
}

pub type IpVtapMode = IpVlanMode;

impl From<u16> for IpVlanMode {
fn from(d: u16) -> Self {
match d {
Expand Down
2 changes: 1 addition & 1 deletion src/link/link_info/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ pub use self::info_data::InfoData;
pub use self::info_port::{InfoPortData, InfoPortKind};
pub use self::infos::{InfoKind, LinkInfo};
pub use self::ipoib::InfoIpoib;
pub use self::ipvlan::{InfoIpVlan, IpVlanMode};
pub use self::ipvlan::{InfoIpVlan, InfoIpVtap, IpVlanMode, IpVtapMode};
pub use self::mac_vlan::{InfoMacVlan, InfoMacVtap, MacVlanMode, MacVtapMode};
pub use self::macsec::{
InfoMacSec, MacSecCipherId, MacSecOffload, MacSecValidate,
Expand Down
10 changes: 5 additions & 5 deletions src/link/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,11 @@ pub use self::link_info::{
BridgePortMulticastRouter, BridgePortState, BridgeQuerierState,
HsrProtocol, InfoBond, InfoBondPort, InfoBridge, InfoBridgePort, InfoData,
InfoGreTap, InfoGreTap6, InfoGreTun, InfoGreTun6, InfoGtp, InfoHsr,
InfoIpVlan, InfoIpoib, InfoKind, InfoMacSec, InfoMacVlan, InfoMacVtap,
InfoPortData, InfoPortKind, InfoSitTun, InfoTun, InfoVeth, InfoVlan,
InfoVrf, InfoVti, InfoVxlan, InfoXfrm, IpVlanMode, LinkInfo, LinkXstats,
MacSecCipherId, MacSecOffload, MacSecValidate, MacVlanMode, MacVtapMode,
MiiStatus, VlanQosMapping,
InfoIpVlan, InfoIpVtap, InfoIpoib, InfoKind, InfoMacSec, InfoMacVlan,
InfoMacVtap, InfoPortData, InfoPortKind, InfoSitTun, InfoTun, InfoVeth,
InfoVlan, InfoVrf, InfoVti, InfoVxlan, InfoXfrm, IpVlanMode, IpVtapMode,
LinkInfo, LinkXstats, MacSecCipherId, MacSecOffload, MacSecValidate,
MacVlanMode, MacVtapMode, MiiStatus, VlanQosMapping,
};
pub use self::link_layer_type::LinkLayerType;
pub use self::link_state::State;
Expand Down
49 changes: 49 additions & 0 deletions src/link/tests/ipvtap.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
// SPDX-License-Identifier: MIT

use netlink_packet_utils::{Emitable, Parseable};

use crate::link::link_flag::LinkFlags;
use crate::link::{
InfoData, InfoIpVtap, InfoKind, IpVtapMode, LinkAttribute, LinkHeader,
LinkInfo, LinkLayerType, LinkMessage, LinkMessageBuffer,
};
use crate::AddressFamily;

#[test]
fn test_ipvtap_link_info() {
let raw: Vec<u8> = vec![
0x00, 0x00, 0x01, 0x00, 0x12, 0x00, 0x00, 0x00, 0x02, 0x10, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x24, 0x00, 0x12, 0x00, 0x0b, 0x00, 0x01, 0x00,
0x69, 0x70, 0x76, 0x74, 0x61, 0x70, 0x00, 0x00, 0x14, 0x00, 0x02, 0x00,
0x06, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x02, 0x00,
0x02, 0x00, 0x00, 0x00,
];

let expected = LinkMessage {
header: LinkHeader {
interface_family: AddressFamily::Unspec,
index: 18,
link_layer_type: LinkLayerType::Ether,
flags: LinkFlags::Broadcast | LinkFlags::Multicast,
change_mask: LinkFlags::empty(),
},
attributes: vec![LinkAttribute::LinkInfo(vec![
LinkInfo::Kind(InfoKind::IpVtap),
LinkInfo::Data(InfoData::IpVtap(vec![
InfoIpVtap::Mode(IpVtapMode::L2),
InfoIpVtap::Flags(2),
])),
])],
};

assert_eq!(
expected,
LinkMessage::parse(&LinkMessageBuffer::new(&raw)).unwrap()
);

let mut buf = vec![0; expected.buffer_len()];

expected.emit(&mut buf);

assert_eq!(buf, raw);
}
2 changes: 2 additions & 0 deletions src/link/tests/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ mod hsr;
#[cfg(test)]
mod ipvlan;
#[cfg(test)]
mod ipvtap;
#[cfg(test)]
mod loopback;
#[cfg(test)]
mod macsec;
Expand Down

0 comments on commit a8d125c

Please sign in to comment.