use netlink_packet_core::{Emitable, Parseable};
use crate::{
link::{
BondAdSelect, BondAllPortActive, BondArpAllTargets, BondArpValidate,
BondFailOverMac, BondLacpRate, BondMode, BondPortState,
BondPrimaryReselect, BondXmitHashPolicy, InfoBond, InfoBondPort,
InfoData, InfoKind, InfoPortData, InfoPortKind, LinkAttribute,
LinkFlags, LinkHeader, LinkInfo, LinkLayerType, LinkMessage,
LinkMessageBuffer, LinkMode, Map, MiiStatus, State,
},
AddressFamily, RouteNetlinkMessage,
};
#[test]
fn test_bond_link_info() {
let raw: Vec<u8> = vec![
0x00, 0x00, 0x01, 0x00, 0x18, 0x00, 0x00, 0x00, 0x43, 0x14, 0x01, 0x00,
0x00, 0x00, 0x00, 0x00, 0xcc, 0x00, 0x12, 0x00, 0x09, 0x00, 0x01, 0x00, 0x62, 0x6f, 0x6e, 0x64, 0x00, 0x00, 0x00, 0x00, 0xbc, 0x00, 0x02, 0x00, 0x05, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x03, 0x00,
0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
0x08, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x1c, 0x00,
0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x06, 0x00, 0x01, 0x00, 0x00, 0x00,
0x08, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x09, 0x00,
0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00,
0x05, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x0d, 0x00,
0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00,
0x08, 0x00, 0x0f, 0x00, 0x01, 0x00, 0x00, 0x00, 0x05, 0x00, 0x10, 0x00,
0x01, 0x00, 0x00, 0x00, 0x05, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00,
0x08, 0x00, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x13, 0x00,
0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x14, 0x00, 0x01, 0x00, 0x00, 0x00,
0x05, 0x00, 0x1d, 0x00, 0x01, 0x00, 0x00, 0x00, 0x05, 0x00, 0x15, 0x00,
0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00,
0x05, 0x00, 0x1b, 0x00, 0x01, 0x00, 0x00, 0x00, 0x05, 0x00, 0x1e, 0x00,
0x02, 0x00, 0x00, 0x00,
];
let expected = LinkMessage {
header: LinkHeader {
interface_family: AddressFamily::Unspec,
index: 24,
link_layer_type: LinkLayerType::Ether,
flags: LinkFlags::Broadcast
| LinkFlags::Controller
| LinkFlags::LowerUp
| LinkFlags::Multicast
| LinkFlags::Running
| LinkFlags::Up,
change_mask: LinkFlags::empty(),
},
attributes: vec![LinkAttribute::LinkInfo(vec![
LinkInfo::Kind(InfoKind::Bond),
LinkInfo::Data(InfoData::Bond(vec![
InfoBond::Mode(BondMode::BalanceRr),
InfoBond::MiiMon(0),
InfoBond::UpDelay(0),
InfoBond::DownDelay(0),
InfoBond::PeerNotifDelay(0),
InfoBond::UseCarrier(true),
InfoBond::ArpInterval(0),
InfoBond::ArpValidate(BondArpValidate::None),
InfoBond::ArpAllTargets(BondArpAllTargets::Any),
InfoBond::PrimaryReselect(BondPrimaryReselect::Always),
InfoBond::FailOverMac(BondFailOverMac::None),
InfoBond::XmitHashPolicy(BondXmitHashPolicy::Layer2),
InfoBond::ResendIgmp(1),
InfoBond::NumPeerNotif(1),
InfoBond::AllPortsActive(BondAllPortActive::Dropped),
InfoBond::MinLinks(0),
InfoBond::LpInterval(1),
InfoBond::PacketsPerPort(1),
InfoBond::AdLacpActive(true),
InfoBond::AdLacpRate(BondLacpRate::Slow),
InfoBond::AdSelect(BondAdSelect::Stable),
InfoBond::TlbDynamicLb(true),
InfoBond::MissedMax(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);
}
#[test]
fn test_bond_port_link_info() {
let raw: Vec<u8> = vec![
0x00, 0x00, 0x01, 0x00, 0x15, 0x00, 0x00, 0x00, 0x43, 0x18, 0x01, 0x00,
0x00, 0x00, 0x00, 0x00, 0x54, 0x00, 0x12, 0x00, 0x09, 0x00, 0x01, 0x00,
0x76, 0x65, 0x74, 0x68, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x04, 0x00,
0x62, 0x6f, 0x6e, 0x64, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x05, 0x00,
0x05, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x02, 0x00,
0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
0x0a, 0x00, 0x04, 0x00, 0x00, 0x23, 0x45, 0x67, 0x89, 0x1a, 0x00, 0x00,
0x06, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x09, 0x00,
0x00, 0x00, 0x00, 0x00,
];
let expected = LinkMessage {
header: LinkHeader {
interface_family: AddressFamily::Unspec,
index: 21,
link_layer_type: LinkLayerType::Ether,
flags: LinkFlags::Broadcast
| LinkFlags::LowerUp
| LinkFlags::Multicast
| LinkFlags::Port
| LinkFlags::Running
| LinkFlags::Up,
change_mask: LinkFlags::empty(),
},
attributes: vec![LinkAttribute::LinkInfo(vec![
LinkInfo::Kind(InfoKind::Veth),
LinkInfo::PortKind(InfoPortKind::Bond),
LinkInfo::PortData(InfoPortData::BondPort(vec![
InfoBondPort::BondPortState(BondPortState::Active),
InfoBondPort::MiiStatus(MiiStatus::Up),
InfoBondPort::LinkFailureCount(0),
InfoBondPort::PermHwaddr(vec![
0x00, 0x23, 0x45, 0x67, 0x89, 0x1a,
]),
InfoBondPort::QueueId(0),
InfoBondPort::Prio(0),
])),
])],
};
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);
}
#[test]
fn test_bond_arp_validate() {
let raw: Vec<u8> = vec![
0x00, 0x00, 0x01, 0x00, 0x05, 0x00, 0x00, 0x00, 0x02, 0x14, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x03, 0x00, 0x62, 0x6f, 0x6e, 0x64,
0x30, 0x00, 0x00, 0x00, 0x08, 0x00, 0x0d, 0x00, 0xe8, 0x03, 0x00, 0x00,
0x05, 0x00, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x05, 0x00, 0x11, 0x00,
0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0xdc, 0x05, 0x00, 0x00,
0x08, 0x00, 0x32, 0x00, 0x44, 0x00, 0x00, 0x00, 0x08, 0x00, 0x33, 0x00,
0xff, 0xff, 0x00, 0x00, 0x08, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x00, 0x00,
0x08, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x1f, 0x00,
0x10, 0x00, 0x00, 0x00, 0x08, 0x00, 0x28, 0x00, 0xff, 0xff, 0x00, 0x00,
0x08, 0x00, 0x29, 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0x00, 0x20, 0x00,
0x10, 0x00, 0x00, 0x00, 0x05, 0x00, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00,
0x09, 0x00, 0x06, 0x00, 0x6e, 0x6f, 0x6f, 0x70, 0x00, 0x00, 0x00, 0x00,
0x08, 0x00, 0x23, 0x00, 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x2f, 0x00,
0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x30, 0x00, 0x01, 0x00, 0x00, 0x00,
0x05, 0x00, 0x27, 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x00, 0x0e, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x01, 0x00,
0x92, 0xb3, 0xba, 0x20, 0xd7, 0xa0, 0x00, 0x00, 0x0a, 0x00, 0x02, 0x00,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
];
let expected = LinkMessage {
header: LinkHeader {
interface_family: AddressFamily::Unspec,
index: 5,
link_layer_type: LinkLayerType::Ether,
flags: LinkFlags::Broadcast
| LinkFlags::Controller
| LinkFlags::Multicast,
change_mask: LinkFlags::empty(),
},
attributes: vec![
LinkAttribute::IfName("bond0".into()),
LinkAttribute::TxQueueLen(1000),
LinkAttribute::OperState(State::Down),
LinkAttribute::Mode(LinkMode::Default),
LinkAttribute::Mtu(1500),
LinkAttribute::MinMtu(68),
LinkAttribute::MaxMtu(65535),
LinkAttribute::Group(0),
LinkAttribute::Promiscuity(0),
LinkAttribute::NumTxQueues(16),
LinkAttribute::GsoMaxSegs(65535),
LinkAttribute::GsoMaxSize(65536),
LinkAttribute::NumRxQueues(16),
LinkAttribute::Carrier(0),
LinkAttribute::Qdisc("noop".into()),
LinkAttribute::CarrierChanges(1),
LinkAttribute::CarrierUpCount(0),
LinkAttribute::CarrierDownCount(1),
LinkAttribute::ProtoDown(0),
LinkAttribute::Map(Map {
memory_start: 0,
memory_end: 0,
base_address: 0,
irq: 0,
dma: 0,
port: 0,
}),
LinkAttribute::Address(vec![0x92, 0xb3, 0xba, 0x20, 0xd7, 0xa0]),
LinkAttribute::Broadcast(vec![0xff, 0xff, 0xff, 0xff, 0xff, 0xff]),
],
};
let packet = RouteNetlinkMessage::NewLink(expected);
let mut buf = vec![0u8; packet.buffer_len()];
packet.emit(&mut buf);
assert_eq!(raw, buf);
}