This repository has been archived by the owner on Oct 26, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 89
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
bridge vlan info: expand VlanInfo of AfSpecBridge
To simplify the efforts on parsing linux bridge vlan filter, this patch is introducing `struct BridgeVlanInfo` to hold VlanInfo of AfSpecBridge. This C struct is defined in `linux/if_bridge.h` as `struct bridge_vlan_info`. Example code included as `dump_packet_link_bridge_vlan.rs`. To try out of linux bridge VLAN filtering, you may: ``` sudo ip link add eth1 type veth peer name eth1.ep sudo ip link add br0 type bridge sudo ip link set eth1 master br0 sudo ip link set eth1 up sudo ip link set eth1.ep up sudo ip link set br0 up sudo bridge vlan add vid 10 pvid untagged dev eth1 sudo bridge vlan add vid 20-4094 dev eth1 sudo ip link set br0 type bridge vlan_filtering 1 cargo run --example dump_packet_link_bridge_vlan ``` The example code is manually tested on kernel 5.14.0-80.el9.x86_64 and 4.18.0-383.el8.x86_64. Signed-off-by: Gris Ge <cnfourt@gmail.com>
- Loading branch information
Showing
2 changed files
with
126 additions
and
5 deletions.
There are no files selected for viewing
82 changes: 82 additions & 0 deletions
82
netlink-packet-route/examples/dump_packet_link_bridge_vlan.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
// SPDX-License-Identifier: MIT | ||
|
||
use netlink_packet_route::{ | ||
nlas::link::Nla, | ||
LinkMessage, | ||
NetlinkHeader, | ||
NetlinkMessage, | ||
NetlinkPayload, | ||
RtnlMessage, | ||
AF_BRIDGE, | ||
NLM_F_DUMP, | ||
NLM_F_REQUEST, | ||
RTEXT_FILTER_BRVLAN_COMPRESSED, | ||
}; | ||
use netlink_sys::{protocols::NETLINK_ROUTE, Socket, SocketAddr}; | ||
|
||
fn main() { | ||
let mut socket = Socket::new(NETLINK_ROUTE).unwrap(); | ||
let _port_number = socket.bind_auto().unwrap().port_number(); | ||
socket.connect(&SocketAddr::new(0, 0)).unwrap(); | ||
|
||
let mut message = LinkMessage::default(); | ||
message.header.interface_family = AF_BRIDGE as u8; | ||
message | ||
.nlas | ||
.push(Nla::ExtMask(RTEXT_FILTER_BRVLAN_COMPRESSED)); | ||
let mut packet = NetlinkMessage { | ||
header: NetlinkHeader::default(), | ||
payload: NetlinkPayload::from(RtnlMessage::GetLink(message)), | ||
}; | ||
packet.header.flags = NLM_F_DUMP | NLM_F_REQUEST; | ||
packet.header.sequence_number = 1; | ||
packet.finalize(); | ||
|
||
let mut buf = vec![0; packet.header.length as usize]; | ||
|
||
// Before calling serialize, it is important to check that the buffer in which we're emitting is big | ||
// enough for the packet, other `serialize()` panics. | ||
assert!(buf.len() == packet.buffer_len()); | ||
packet.serialize(&mut buf[..]); | ||
|
||
println!(">>> {:?}", packet); | ||
socket.send(&buf[..], 0).unwrap(); | ||
|
||
let mut receive_buffer = vec![0; 4096]; | ||
let mut offset = 0; | ||
|
||
// we set the NLM_F_DUMP flag so we expect a multipart rx_packet in response. | ||
loop { | ||
let size = socket.recv(&mut &mut receive_buffer[..], 0).unwrap(); | ||
|
||
loop { | ||
let bytes = &receive_buffer[offset..]; | ||
// Note that we're parsing a NetlinkBuffer<&&[u8]>, NOT a NetlinkBuffer<&[u8]> here. | ||
// This is important because Parseable<NetlinkMessage> is only implemented for | ||
// NetlinkBuffer<&'a T>, where T implements AsRef<[u8] + 'a. This is not | ||
// particularly user friendly, but this is a low level library anyway. | ||
// | ||
// Note also that the same could be written more explicitely with: | ||
// | ||
// let rx_packet = | ||
// <NetlinkBuffer<_> as Parseable<NetlinkMessage>>::parse(NetlinkBuffer::new(&bytes)) | ||
// .unwrap(); | ||
// | ||
let rx_packet: NetlinkMessage<RtnlMessage> = | ||
NetlinkMessage::deserialize(bytes).unwrap(); | ||
|
||
println!("<<< {:?}", rx_packet); | ||
|
||
if rx_packet.payload == NetlinkPayload::Done { | ||
println!("Done!"); | ||
return; | ||
} | ||
|
||
offset += rx_packet.header.length as usize; | ||
if offset == size || rx_packet.header.length == 0 { | ||
offset = 0; | ||
break; | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters