Skip to content

Commit e26b489

Browse files
little-dudecathay4t
authored andcommitted
use bitflags for LinkFlags
1 parent b337e00 commit e26b489

File tree

18 files changed

+192
-336
lines changed

18 files changed

+192
-336
lines changed

src/link/header.rs

Lines changed: 10 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,9 @@ use netlink_packet_utils::{
66
DecodeError,
77
};
88

9-
use crate::{
10-
link::{link_flag::VecLinkFlag, LinkFlag, LinkLayerType},
11-
AddressFamily,
12-
};
9+
use crate::{link::LinkLayerType, AddressFamily};
10+
11+
use super::link_flag::LinkFlags;
1312

1413
const LINK_HEADER_LEN: usize = 16;
1514

@@ -65,14 +64,10 @@ pub struct LinkHeader {
6564
/// implemented.
6665
pub link_layer_type: LinkLayerType,
6766
/// State of the link, described by a combinations of `IFF_*`
68-
/// constants, for instance `vec![LinkFlag::Up, LinkFlag::LowerUp]`.
69-
/// To convert `Vec<LinkFlag>` into `u32`, you may:
70-
/// `u32::from(&VecLinkFlag(Vec<LinkFlag>)`
71-
/// To convert `u32` to `Vec<LinkFlag>`, you may:
72-
/// `VecLinkFlag::from(u32).0`
73-
pub flags: Vec<LinkFlag>,
67+
/// constants.
68+
pub flags: LinkFlags,
7469
/// Change mask for the `flags` field.
75-
pub change_mask: Vec<LinkFlag>,
70+
pub change_mask: LinkFlags,
7671
}
7772

7873
impl Emitable for LinkHeader {
@@ -84,11 +79,9 @@ impl Emitable for LinkHeader {
8479
let mut packet = LinkMessageBuffer::new(buffer);
8580
packet.set_interface_family(u8::from(self.interface_family));
8681
packet.set_link_index(self.index);
87-
packet.set_change_mask(u32::from(&VecLinkFlag(
88-
self.change_mask.to_vec(),
89-
)));
82+
packet.set_change_mask(self.change_mask.bits());
9083
packet.set_link_layer_type(u16::from(self.link_layer_type));
91-
packet.set_flags(u32::from(&VecLinkFlag(self.flags.to_vec())));
84+
packet.set_flags(self.flags.bits());
9285
}
9386
}
9487

@@ -98,8 +91,8 @@ impl<T: AsRef<[u8]>> Parseable<LinkMessageBuffer<T>> for LinkHeader {
9891
interface_family: buf.interface_family().into(),
9992
link_layer_type: buf.link_layer_type().into(),
10093
index: buf.link_index(),
101-
change_mask: VecLinkFlag::from(buf.change_mask()).0,
102-
flags: VecLinkFlag::from(buf.flags()).0,
94+
change_mask: LinkFlags::from_bits_retain(buf.change_mask()),
95+
flags: LinkFlags::from_bits_retain(buf.flags()),
10396
})
10497
}
10598
}

src/link/link_flag.rs

Lines changed: 29 additions & 153 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
// SPDX-License-Identifier: MIT
22

3+
use std::fmt;
4+
35
const IFF_UP: u32 = 1 << 0;
46
const IFF_BROADCAST: u32 = 1 << 1;
57
const IFF_DEBUG: u32 = 1 << 2;
@@ -22,161 +24,35 @@ const IFF_LOWER_UP: u32 = 1 << 16;
2224
const IFF_DORMANT: u32 = 1 << 17;
2325
const IFF_ECHO: u32 = 1 << 18;
2426

25-
#[derive(Debug, PartialEq, Eq, Clone, Default)]
26-
pub(crate) struct VecLinkFlag(pub Vec<LinkFlag>);
27-
28-
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
29-
#[non_exhaustive]
30-
pub enum LinkFlag {
31-
Up,
32-
Broadcast,
33-
Debug,
34-
Loopback,
35-
Pointopoint,
36-
Notrailers,
37-
Running,
38-
Noarp,
39-
Promisc,
40-
Allmulti,
41-
Controller,
42-
Port,
43-
Multicast,
44-
Portsel,
45-
Automedia,
46-
Dynamic,
47-
LowerUp,
48-
Dormant,
49-
Echo,
50-
Other(u32),
51-
}
52-
53-
impl From<u32> for LinkFlag {
54-
fn from(d: u32) -> Self {
55-
match d {
56-
IFF_UP => Self::Up,
57-
IFF_BROADCAST => Self::Broadcast,
58-
IFF_DEBUG => Self::Debug,
59-
IFF_LOOPBACK => Self::Loopback,
60-
IFF_POINTOPOINT => Self::Pointopoint,
61-
IFF_NOTRAILERS => Self::Notrailers,
62-
IFF_RUNNING => Self::Running,
63-
IFF_NOARP => Self::Noarp,
64-
IFF_PROMISC => Self::Promisc,
65-
IFF_ALLMULTI => Self::Allmulti,
66-
IFF_CONTROLLER => Self::Controller,
67-
IFF_PORT => Self::Port,
68-
IFF_MULTICAST => Self::Multicast,
69-
IFF_PORTSEL => Self::Portsel,
70-
IFF_AUTOMEDIA => Self::Automedia,
71-
IFF_DYNAMIC => Self::Dynamic,
72-
IFF_LOWER_UP => Self::LowerUp,
73-
IFF_DORMANT => Self::Dormant,
74-
IFF_ECHO => Self::Echo,
75-
_ => Self::Other(d),
76-
}
77-
}
78-
}
79-
80-
impl From<LinkFlag> for u32 {
81-
fn from(v: LinkFlag) -> u32 {
82-
match v {
83-
LinkFlag::Up => IFF_UP,
84-
LinkFlag::Broadcast => IFF_BROADCAST,
85-
LinkFlag::Debug => IFF_DEBUG,
86-
LinkFlag::Loopback => IFF_LOOPBACK,
87-
LinkFlag::Pointopoint => IFF_POINTOPOINT,
88-
LinkFlag::Notrailers => IFF_NOTRAILERS,
89-
LinkFlag::Running => IFF_RUNNING,
90-
LinkFlag::Noarp => IFF_NOARP,
91-
LinkFlag::Promisc => IFF_PROMISC,
92-
LinkFlag::Allmulti => IFF_ALLMULTI,
93-
LinkFlag::Controller => IFF_CONTROLLER,
94-
LinkFlag::Port => IFF_PORT,
95-
LinkFlag::Multicast => IFF_MULTICAST,
96-
LinkFlag::Portsel => IFF_PORTSEL,
97-
LinkFlag::Automedia => IFF_AUTOMEDIA,
98-
LinkFlag::Dynamic => IFF_DYNAMIC,
99-
LinkFlag::LowerUp => IFF_LOWER_UP,
100-
LinkFlag::Dormant => IFF_DORMANT,
101-
LinkFlag::Echo => IFF_ECHO,
102-
LinkFlag::Other(i) => i,
103-
}
104-
}
105-
}
106-
107-
impl std::fmt::Display for LinkFlag {
108-
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
109-
match self {
110-
Self::Up => write!(f, "UP"),
111-
Self::Broadcast => write!(f, "BROADCAST"),
112-
Self::Debug => write!(f, "DEBUG"),
113-
Self::Loopback => write!(f, "LOOPBACK"),
114-
Self::Pointopoint => write!(f, "POINTOPOINT"),
115-
Self::Notrailers => write!(f, "NOTRAILERS"),
116-
Self::Running => write!(f, "RUNNING"),
117-
Self::Noarp => write!(f, "NOARP"),
118-
Self::Promisc => write!(f, "PROMISC"),
119-
Self::Allmulti => write!(f, "ALLMULTI"),
120-
Self::Controller => write!(f, "CONTROLLER"),
121-
Self::Port => write!(f, "PORT"),
122-
Self::Multicast => write!(f, "MULTICAST"),
123-
Self::Portsel => write!(f, "PORTSEL"),
124-
Self::Automedia => write!(f, "AUTOMEDIA"),
125-
Self::Dynamic => write!(f, "DYNAMIC"),
126-
Self::LowerUp => write!(f, "LOWER_UP"),
127-
Self::Dormant => write!(f, "DORMANT"),
128-
Self::Echo => write!(f, "ECHO"),
129-
Self::Other(i) => write!(f, "Other({})", i),
130-
}
131-
}
132-
}
133-
134-
// Please sort this list.
135-
const ALL_LINK_FLAGS: [LinkFlag; 19] = [
136-
LinkFlag::Allmulti,
137-
LinkFlag::Automedia,
138-
LinkFlag::Broadcast,
139-
LinkFlag::Controller,
140-
LinkFlag::Debug,
141-
LinkFlag::Dormant,
142-
LinkFlag::Dynamic,
143-
LinkFlag::Echo,
144-
LinkFlag::Loopback,
145-
LinkFlag::LowerUp,
146-
LinkFlag::Multicast,
147-
LinkFlag::Noarp,
148-
LinkFlag::Notrailers,
149-
LinkFlag::Pointopoint,
150-
LinkFlag::Port,
151-
LinkFlag::Portsel,
152-
LinkFlag::Promisc,
153-
LinkFlag::Running,
154-
LinkFlag::Up,
155-
];
156-
157-
impl From<u32> for VecLinkFlag {
158-
fn from(d: u32) -> Self {
159-
let mut got: u32 = 0;
160-
let mut ret = Vec::new();
161-
for flag in ALL_LINK_FLAGS {
162-
if (d & u32::from(flag)) > 0 {
163-
ret.push(flag);
164-
got += u32::from(flag);
165-
}
166-
}
167-
if got != d {
168-
ret.push(LinkFlag::Other(d - got));
169-
}
170-
Self(ret)
27+
bitflags! {
28+
#[derive(Debug, PartialEq, Eq, Clone, Copy, Default)]
29+
#[non_exhaustive]
30+
pub struct LinkFlags: u32 {
31+
const Up = IFF_UP;
32+
const Broadcast = IFF_BROADCAST;
33+
const Debug = IFF_DEBUG;
34+
const Loopback = IFF_LOOPBACK;
35+
const Pointopoint = IFF_POINTOPOINT;
36+
const Notrailers = IFF_NOTRAILERS;
37+
const Running = IFF_RUNNING;
38+
const Noarp = IFF_NOARP;
39+
const Promisc = IFF_PROMISC;
40+
const Allmulti = IFF_ALLMULTI;
41+
const Controller = IFF_CONTROLLER;
42+
const Port = IFF_PORT;
43+
const Multicast = IFF_MULTICAST;
44+
const Portsel = IFF_PORTSEL;
45+
const Automedia = IFF_AUTOMEDIA;
46+
const Dynamic = IFF_DYNAMIC;
47+
const LowerUp = IFF_LOWER_UP;
48+
const Dormant = IFF_DORMANT;
49+
const Echo = IFF_ECHO;
50+
const _ = !0;
17151
}
17252
}
17353

174-
impl From<&VecLinkFlag> for u32 {
175-
fn from(v: &VecLinkFlag) -> u32 {
176-
let mut d: u32 = 0;
177-
for flag in &v.0 {
178-
d += u32::from(*flag);
179-
}
180-
d
54+
impl fmt::Display for LinkFlags {
55+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
56+
bitflags::parser::to_writer(self, f)
18157
}
18258
}

src/link/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ mod down_reason;
77
mod event;
88
pub(crate) mod ext_mask;
99
mod header;
10-
pub(crate) mod link_flag;
10+
mod link_flag;
1111
mod link_info;
1212
mod link_layer_type;
1313
mod link_state;
@@ -36,7 +36,7 @@ pub use self::down_reason::LinkProtocolDownReason;
3636
pub use self::event::LinkEvent;
3737
pub use self::ext_mask::LinkExtentMask;
3838
pub use self::header::{LinkHeader, LinkMessageBuffer};
39-
pub use self::link_flag::LinkFlag;
39+
pub use self::link_flag::LinkFlags;
4040
pub use self::link_info::{
4141
BondAdInfo, BondPortState, BridgeId, BridgeIdBuffer,
4242
BridgePortMulticastRouter, BridgePortState, BridgeQuerierState,

src/link/tests/bond.rs

Lines changed: 16 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,10 @@
22

33
use netlink_packet_utils::{Emitable, Parseable};
44

5+
use crate::link::link_flag::LinkFlags;
56
use crate::link::{
67
BondPortState, InfoBond, InfoBondPort, InfoData, InfoKind, InfoPortData,
7-
InfoPortKind, LinkAttribute, LinkFlag, LinkHeader, LinkInfo, LinkLayerType,
8+
InfoPortKind, LinkAttribute, LinkHeader, LinkInfo, LinkLayerType,
89
LinkMessage, LinkMessageBuffer, MiiStatus,
910
};
1011
use crate::AddressFamily;
@@ -44,15 +45,13 @@ fn test_bond_link_info() {
4445
interface_family: AddressFamily::Unspec,
4546
index: 24,
4647
link_layer_type: LinkLayerType::Ether,
47-
flags: vec![
48-
LinkFlag::Broadcast,
49-
LinkFlag::Controller,
50-
LinkFlag::LowerUp,
51-
LinkFlag::Multicast,
52-
LinkFlag::Running,
53-
LinkFlag::Up,
54-
],
55-
change_mask: vec![],
48+
flags: LinkFlags::Broadcast
49+
| LinkFlags::Controller
50+
| LinkFlags::LowerUp
51+
| LinkFlags::Multicast
52+
| LinkFlags::Running
53+
| LinkFlags::Up,
54+
change_mask: LinkFlags::empty(),
5655
},
5756
attributes: vec![LinkAttribute::LinkInfo(vec![
5857
LinkInfo::Kind(InfoKind::Bond),
@@ -115,15 +114,13 @@ fn test_bond_port_link_info() {
115114
interface_family: AddressFamily::Unspec,
116115
index: 21,
117116
link_layer_type: LinkLayerType::Ether,
118-
flags: vec![
119-
LinkFlag::Broadcast,
120-
LinkFlag::LowerUp,
121-
LinkFlag::Multicast,
122-
LinkFlag::Port,
123-
LinkFlag::Running,
124-
LinkFlag::Up,
125-
],
126-
change_mask: vec![],
117+
flags: LinkFlags::Broadcast
118+
| LinkFlags::LowerUp
119+
| LinkFlags::Multicast
120+
| LinkFlags::Port
121+
| LinkFlags::Running
122+
| LinkFlags::Up,
123+
change_mask: LinkFlags::empty(),
127124
},
128125
attributes: vec![LinkAttribute::LinkInfo(vec![
129126
LinkInfo::Kind(InfoKind::Veth),

src/link/tests/bridge.rs

Lines changed: 15 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,13 @@ use netlink_packet_utils::{
66
};
77

88
use crate::link::{
9-
af_spec::VecAfSpecBridge, AfSpecBridge, AfSpecInet, AfSpecInet6,
10-
AfSpecUnspec, BridgeId, BridgePortMulticastRouter, BridgePortState,
11-
BridgeVlanInfo, Inet6CacheInfo, Inet6DevConf, Inet6IfaceFlags, InetDevConf,
12-
InfoBridge, InfoBridgePort, InfoData, InfoKind, InfoPortData, InfoPortKind,
13-
LinkAttribute, LinkFlag, LinkHeader, LinkInfo, LinkLayerType, LinkMessage,
14-
LinkMessageBuffer, LinkXdp, Map, State, Stats, Stats64, XdpAttached,
9+
af_spec::VecAfSpecBridge, link_flag::LinkFlags, AfSpecBridge, AfSpecInet,
10+
AfSpecInet6, AfSpecUnspec, BridgeId, BridgePortMulticastRouter,
11+
BridgePortState, BridgeVlanInfo, Inet6CacheInfo, Inet6DevConf,
12+
Inet6IfaceFlags, InetDevConf, InfoBridge, InfoBridgePort, InfoData,
13+
InfoKind, InfoPortData, InfoPortKind, LinkAttribute, LinkHeader, LinkInfo,
14+
LinkLayerType, LinkMessage, LinkMessageBuffer, LinkXdp, Map, State, Stats,
15+
Stats64, XdpAttached,
1516
};
1617
use crate::AddressFamily;
1718

@@ -146,14 +147,12 @@ fn test_parse_link_bridge_no_extention_mask() {
146147
interface_family: AddressFamily::Unspec,
147148
index: 53,
148149
link_layer_type: LinkLayerType::Ether,
149-
flags: vec![
150-
LinkFlag::Broadcast,
151-
LinkFlag::LowerUp,
152-
LinkFlag::Multicast,
153-
LinkFlag::Running,
154-
LinkFlag::Up,
155-
],
156-
change_mask: vec![],
150+
flags: LinkFlags::Broadcast
151+
| LinkFlags::LowerUp
152+
| LinkFlags::Multicast
153+
| LinkFlags::Running
154+
| LinkFlags::Up,
155+
change_mask: LinkFlags::empty(),
157156
},
158157
attributes: vec![
159158
LinkAttribute::IfName("br0".into()),
@@ -491,8 +490,8 @@ fn test_bridge_port_link_info() {
491490
interface_family: AddressFamily::Unspec,
492491
index: 7,
493492
link_layer_type: LinkLayerType::Ether,
494-
flags: vec![LinkFlag::Broadcast, LinkFlag::Multicast],
495-
change_mask: vec![],
493+
flags: LinkFlags::Broadcast | LinkFlags::Multicast,
494+
change_mask: LinkFlags::empty(),
496495
},
497496
attributes: vec![LinkAttribute::LinkInfo(vec![
498497
LinkInfo::Kind(InfoKind::Veth),

0 commit comments

Comments
 (0)