Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

link: ipvtap: support ipvtap mod. ipvtap is a alias to ipvlan mode. #109

Merged
merged 1 commit into from
Mar 31, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 @@
}
}

#[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(),

Check warning on line 85 in src/link/link_info/ipvlan.rs

View check run for this annotation

Codecov / codecov/patch

src/link/link_info/ipvlan.rs#L85

Added line #L85 was not covered by tests
}
}

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),

Check warning on line 94 in src/link/link_info/ipvlan.rs

View check run for this annotation

Codecov / codecov/patch

src/link/link_info/ipvlan.rs#L94

Added line #L94 was not covered by tests
}
}

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

Check warning on line 103 in src/link/link_info/ipvlan.rs

View check run for this annotation

Codecov / codecov/patch

src/link/link_info/ipvlan.rs#L103

Added line #L103 was not covered by tests
}
}
}

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)"
))?),

Check warning on line 124 in src/link/link_info/ipvlan.rs

View check run for this annotation

Codecov / codecov/patch

src/link/link_info/ipvlan.rs#L122-L124

Added lines #L122 - L124 were not covered by tests
})
}
}

const IPVLAN_MODE_L2: u16 = 0;
const IPVLAN_MODE_L3: u16 = 1;
const IPVLAN_MODE_L3S: u16 = 2;
Expand All @@ -82,6 +139,8 @@
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
Loading