Skip to content

Commit 83c9689

Browse files
liangwen12yearcathay4t
authored andcommitted
Support bond port settings
The developer wants to use rtnetlink to get and set bond port settings for a specific bond port, therefore, support parsing the bond port settings in netlink-route-packet rust crate. Signed-off-by: Wen Liang <[email protected]>
1 parent 0d1bb1f commit 83c9689

File tree

4 files changed

+353
-20
lines changed

4 files changed

+353
-20
lines changed

src/rtnl/constants.rs

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1032,16 +1032,25 @@ pub const IFLA_BOND_AD_INFO_ACTOR_KEY: u16 = 3;
10321032
pub const IFLA_BOND_AD_INFO_PARTNER_KEY: u16 = 4;
10331033
pub const IFLA_BOND_AD_INFO_PARTNER_MAC: u16 = 5;
10341034

1035-
// pub const IFLA_BOND_SLAVE_UNSPEC: int = 0;
1036-
// pub const IFLA_BOND_SLAVE_STATE: int = 1;
1037-
// pub const IFLA_BOND_SLAVE_MII_STATUS: int = 2;
1038-
// pub const IFLA_BOND_SLAVE_LINK_FAILURE_COUNT: int = 3;
1039-
// pub const IFLA_BOND_SLAVE_PERM_HWADDR: int = 4;
1040-
// pub const IFLA_BOND_SLAVE_QUEUE_ID: int = 5;
1041-
// pub const IFLA_BOND_SLAVE_AD_AGGREGATOR_ID: int = 6;
1042-
// pub const IFLA_BOND_SLAVE_AD_ACTOR_OPER_PORT_STATE: int = 7;
1043-
// pub const IFLA_BOND_SLAVE_AD_PARTNER_OPER_PORT_STATE: int = 8;
1044-
//
1035+
pub const IFLA_BOND_SLAVE_UNSPEC: u16 = 0;
1036+
pub const IFLA_BOND_SLAVE_STATE: u16 = 1;
1037+
pub const IFLA_BOND_SLAVE_MII_STATUS: u16 = 2;
1038+
pub const IFLA_BOND_SLAVE_LINK_FAILURE_COUNT: u16 = 3;
1039+
pub const IFLA_BOND_SLAVE_PERM_HWADDR: u16 = 4;
1040+
pub const IFLA_BOND_SLAVE_QUEUE_ID: u16 = 5;
1041+
pub const IFLA_BOND_SLAVE_AD_AGGREGATOR_ID: u16 = 6;
1042+
pub const IFLA_BOND_SLAVE_AD_ACTOR_OPER_PORT_STATE: u16 = 7;
1043+
pub const IFLA_BOND_SLAVE_AD_PARTNER_OPER_PORT_STATE: u16 = 8;
1044+
pub const IFLA_BOND_SLAVE_PRIO: u16 = 9;
1045+
1046+
pub const IFLA_BOND_SLAVE_STATE_ACTIVE: u8 = 0;
1047+
pub const IFLA_BOND_SLAVE_STATE_BACKUP: u8 = 1;
1048+
1049+
pub const IFLA_BOND_SLAVE_MII_STATUS_UP: u8 = 0;
1050+
pub const IFLA_BOND_SLAVE_MII_STATUS_GOING_DOWN: u8 = 1;
1051+
pub const IFLA_BOND_SLAVE_MII_STATUS_DOWN: u8 = 2;
1052+
pub const IFLA_BOND_SLAVE_MII_STATUS_GOING_BACK: u8 = 3;
1053+
10451054
// pub const IFLA_VF_INFO_UNSPEC: int = 0;
10461055
// pub const IFLA_VF_INFO: int = 1;
10471056
//

src/rtnl/link/nlas/bond_port.rs

Lines changed: 179 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,179 @@
1+
// SPDX-License-Identifier: MIT
2+
use anyhow::Context;
3+
use byteorder::{ByteOrder, NativeEndian};
4+
use netlink_packet_utils::{
5+
nla::{DefaultNla, Nla, NlaBuffer},
6+
parsers::{parse_i32, parse_u16, parse_u32, parse_u8},
7+
traits::Parseable,
8+
DecodeError,
9+
};
10+
11+
use crate::constants::*;
12+
13+
#[derive(Debug, Clone, Copy, Eq, PartialEq)]
14+
#[non_exhaustive]
15+
pub enum SlaveState {
16+
Active,
17+
Backup,
18+
Other(u8),
19+
}
20+
21+
impl From<u8> for SlaveState {
22+
fn from(value: u8) -> Self {
23+
use self::SlaveState::*;
24+
match value {
25+
IFLA_BOND_SLAVE_STATE_ACTIVE => Active,
26+
IFLA_BOND_SLAVE_STATE_BACKUP => Backup,
27+
_ => Other(value),
28+
}
29+
}
30+
}
31+
32+
impl From<SlaveState> for u8 {
33+
fn from(value: SlaveState) -> Self {
34+
use self::SlaveState::*;
35+
match value {
36+
Active => IFLA_BOND_SLAVE_STATE_ACTIVE,
37+
Backup => IFLA_BOND_SLAVE_STATE_BACKUP,
38+
Other(other) => other,
39+
}
40+
}
41+
}
42+
43+
#[derive(Debug, Clone, Copy, Eq, PartialEq)]
44+
#[non_exhaustive]
45+
pub enum MiiStatus {
46+
Up,
47+
GoingDown,
48+
Down,
49+
GoingBack,
50+
Other(u8),
51+
}
52+
53+
impl From<u8> for MiiStatus {
54+
fn from(value: u8) -> Self {
55+
use self::MiiStatus::*;
56+
match value {
57+
IFLA_BOND_SLAVE_MII_STATUS_UP => Up,
58+
IFLA_BOND_SLAVE_MII_STATUS_GOING_DOWN => GoingDown,
59+
IFLA_BOND_SLAVE_MII_STATUS_DOWN => Down,
60+
IFLA_BOND_SLAVE_MII_STATUS_GOING_BACK => GoingBack,
61+
_ => Other(value),
62+
}
63+
}
64+
}
65+
66+
impl From<MiiStatus> for u8 {
67+
fn from(value: MiiStatus) -> Self {
68+
use self::MiiStatus::*;
69+
match value {
70+
Up => IFLA_BOND_SLAVE_MII_STATUS_UP,
71+
GoingDown => IFLA_BOND_SLAVE_MII_STATUS_GOING_DOWN,
72+
Down => IFLA_BOND_SLAVE_MII_STATUS_DOWN,
73+
GoingBack => IFLA_BOND_SLAVE_MII_STATUS_GOING_BACK,
74+
Other(other) => other,
75+
}
76+
}
77+
}
78+
79+
#[derive(Debug, PartialEq, Eq, Clone)]
80+
#[non_exhaustive]
81+
pub enum InfoBondPort {
82+
LinkFailureCount(u32),
83+
MiiStatus(MiiStatus),
84+
PermHwaddr(Vec<u8>),
85+
Prio(i32),
86+
QueueId(u16),
87+
SlaveState(SlaveState),
88+
Other(DefaultNla),
89+
}
90+
91+
impl Nla for InfoBondPort {
92+
#[rustfmt::skip]
93+
fn value_len(&self) -> usize {
94+
use self::InfoBondPort::*;
95+
match self {
96+
QueueId(_)
97+
=> 2,
98+
LinkFailureCount(_) |
99+
Prio(_)
100+
=> 4,
101+
PermHwaddr(ref bytes)
102+
=> bytes.len(),
103+
MiiStatus(_) => 1,
104+
SlaveState(_) => 1,
105+
Other(nla)
106+
=> nla.value_len(),
107+
}
108+
}
109+
110+
#[rustfmt::skip]
111+
fn emit_value(&self, buffer: &mut [u8]) {
112+
use self::InfoBondPort::*;
113+
match self {
114+
QueueId(ref value)
115+
=> NativeEndian::write_u16(buffer, *value),
116+
PermHwaddr(ref bytes)
117+
=> buffer.copy_from_slice(bytes.as_slice()),
118+
Prio(ref value)
119+
=> NativeEndian::write_i32(buffer, *value),
120+
LinkFailureCount(value)
121+
=> NativeEndian::write_u32(buffer, *value),
122+
MiiStatus(state) => buffer[0] = (*state).into(),
123+
SlaveState(state) => buffer[0] = (*state).into(),
124+
Other(nla)
125+
=> nla.emit_value(buffer),
126+
}
127+
}
128+
129+
fn kind(&self) -> u16 {
130+
use self::InfoBondPort::*;
131+
132+
match self {
133+
LinkFailureCount(_) => IFLA_BOND_SLAVE_LINK_FAILURE_COUNT,
134+
MiiStatus(_) => IFLA_BOND_SLAVE_MII_STATUS,
135+
PermHwaddr(_) => IFLA_BOND_SLAVE_PERM_HWADDR,
136+
Prio(_) => IFLA_BOND_SLAVE_PRIO,
137+
QueueId(_) => IFLA_BOND_SLAVE_QUEUE_ID,
138+
SlaveState(_) => IFLA_BOND_SLAVE_STATE,
139+
Other(nla) => nla.kind(),
140+
}
141+
}
142+
}
143+
144+
impl<'a, T: AsRef<[u8]> + ?Sized> Parseable<NlaBuffer<&'a T>> for InfoBondPort {
145+
fn parse(buf: &NlaBuffer<&'a T>) -> Result<Self, DecodeError> {
146+
use self::InfoBondPort::*;
147+
let payload = buf.value();
148+
Ok(match buf.kind() {
149+
IFLA_BOND_SLAVE_LINK_FAILURE_COUNT => {
150+
LinkFailureCount(parse_u32(payload).context(
151+
"invalid IFLA_BOND_SLAVE_LINK_FAILURE_COUNT value",
152+
)?)
153+
}
154+
IFLA_BOND_SLAVE_MII_STATUS => MiiStatus(
155+
parse_u8(payload)
156+
.context("invalid IFLA_BOND_SLAVE_MII_STATUS value")?
157+
.into(),
158+
),
159+
IFLA_BOND_SLAVE_PERM_HWADDR => PermHwaddr(payload.to_vec()),
160+
IFLA_BOND_SLAVE_PRIO => Prio(
161+
parse_i32(payload)
162+
.context("invalid IFLA_BOND_SLAVE_PRIO value")?,
163+
),
164+
IFLA_BOND_SLAVE_QUEUE_ID => QueueId(
165+
parse_u16(payload)
166+
.context("invalid IFLA_BOND_SLAVE_QUEUE_ID value")?,
167+
),
168+
IFLA_BOND_SLAVE_STATE => SlaveState(
169+
parse_u8(payload)
170+
.context("invalid IFLA_BOND_SLAVE_STATE value")?
171+
.into(),
172+
),
173+
kind => Other(
174+
DefaultNla::parse(buf)
175+
.context(format!("unknown NLA type {kind}"))?,
176+
),
177+
})
178+
}
179+
}

0 commit comments

Comments
 (0)