1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
// SPDX-License-Identifier: MIT
use netlink_packet_core::{Emitable, Parseable};
use crate::{
link::{
link_flag::LinkFlags, InfoData, InfoKind, InfoVeth, LinkAttribute,
LinkHeader, LinkInfo, LinkLayerType, LinkMessage, LinkMessageBuffer,
},
AddressFamily,
};
#[test]
fn test_veth_get_link_info() {
let raw: Vec<u8> = vec![
0x00, 0x00, // AF_UNSPEC and reserved
0x01, 0x00, // Link layer type ethernet(1)
0x19, 0x00, 0x00, 0x00, // iface index 25
0x43, 0x10, 0x01, 0x00, // flags
0x00, 0x00, 0x00, 0x00, // changed flags0
0x10, 0x00, // length 16
0x12, 0x00, // IFLA_LINKINFO 18
0x09, 0x00, // length 09
0x01, 0x00, // IFLA_INFO_KIND
0x76, 0x65, 0x74, 0x68, 0x00, // 'bond\0'
0x00, 0x00, 0x00, // padding
];
let expected = LinkMessage {
header: LinkHeader {
interface_family: AddressFamily::Unspec,
index: 25,
link_layer_type: LinkLayerType::Ether,
flags: LinkFlags::Broadcast
| LinkFlags::LowerUp
| LinkFlags::Multicast
| LinkFlags::Running
| LinkFlags::Up,
change_mask: LinkFlags::empty(),
},
attributes: vec![LinkAttribute::LinkInfo(vec![LinkInfo::Kind(
InfoKind::Veth,
)])],
};
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_crate_veth() {
// With `iproute 6.5.0`, the IFLA_INFO_KIND will not use NULL terminated
// string.
// This is bug of iproute: https://issues.redhat.com/browse/RHEL-14964
// The correct way is NULL terminated `IFLA_INFO_KIND`, hence below packet
// is different from what iproute generate.
let raw: Vec<u8> = vec![
0x00, // interface family AF_UNSPEC
0x00, // reserved
0x00, 0x00, // link layer type 0
0x00, 0x00, 0x00, 0x00, // iface index 0
0x00, 0x00, 0x00, 0x00, // device flags 0
0x00, 0x00, 0x00, 0x00, // change flags 0
0x0a, 0x00, // length 10
0x03, 0x00, // IFLA_IFNAME
0x76, 0x65, 0x74, 0x68, 0x31, 0x00, 0x00, 0x00, // "veth0\0"
0x38, 0x00, // length 56
0x12, 0x00, // IFLA_LINKINFO 18
0x09, 0x00, // length 9
0x01, 0x00, // IFLA_INFO_KIND 1
0x76, 0x65, 0x74, 0x68, 0x00, // 'veth\0'
0x00, 0x00, 0x00, // padding
0x28, 0x00, // length 40
0x02, 0x00, // IFLA_INFO_DATA 2
0x24, 0x00, // length 36
0x01, 0x00, // VETH_INFO_PEER 1
0x00, // Netlink Message header: family AF_UNSPEC
0x00, // reserved
0x00, 0x00, // link layer type 0
0x00, 0x00, 0x00, 0x00, // iface index 0
0x00, 0x00, 0x00, 0x00, // device flags 0
0x00, 0x00, 0x00, 0x00, // change flags 0
0x0d, 0x00, // length 16
0x03, 0x00, // IFLA_IFNAME 3
0x76, 0x65, 0x74, 0x68, 0x31, 0x2d, 0x65, 0x70,
0x00, // "veth1-ep\0"
0x00, 0x00, 0x00, // padding
];
let expected = LinkMessage {
attributes: vec![
LinkAttribute::IfName("veth1".to_string()),
LinkAttribute::LinkInfo(vec![
LinkInfo::Kind(InfoKind::Veth),
LinkInfo::Data(InfoData::Veth(InfoVeth::Peer(LinkMessage {
attributes: vec![LinkAttribute::IfName(
"veth1-ep".to_string(),
)],
..Default::default()
}))),
]),
],
..Default::default()
};
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);
}