Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

support NHFLAGS [ onlink | pervasive ] #51

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
94 changes: 94 additions & 0 deletions examples/new_route.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
// SPDX-License-Identifier: MIT

use netlink_packet_core::{
NetlinkHeader, NetlinkMessage, NetlinkPayload, NLM_F_ACK, NLM_F_CREATE,
NLM_F_EXCL, NLM_F_REQUEST,
};
use netlink_packet_route::{
constants::AF_INET, route, RouteFlags, RouteHeader, RouteMessage,
RtnlMessage, RTN_UNICAST, RTPROT_BOOT, RT_SCOPE_UNIVERSE, RT_TABLE_MAIN,
};
use netlink_sys::{protocols::NETLINK_ROUTE, Socket, SocketAddr};
use std::net::Ipv4Addr;

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 route_msg_hdr = RouteHeader {
address_family: AF_INET as u8,
table: RT_TABLE_MAIN,
scope: RT_SCOPE_UNIVERSE,
protocol: RTPROT_BOOT,
kind: RTN_UNICAST,
source_prefix_length: 0,
destination_prefix_length: 32,
flags: RouteFlags::RTNH_F_ONLINK,
..Default::default()
};

let mut route_msg = RouteMessage::default();
route_msg.header = route_msg_hdr;
route_msg.nlas = vec![
// lo
route::Nla::Oif(1),
route::Nla::Gateway(
"169.254.1.1".parse::<Ipv4Addr>().unwrap().octets().to_vec(),
),
route::Nla::Destination(
"1.1.1.1".parse::<Ipv4Addr>().unwrap().octets().to_vec(),
),
];
let mut nl_hdr = NetlinkHeader::default();
nl_hdr.flags = NLM_F_REQUEST | NLM_F_CREATE | NLM_F_EXCL | NLM_F_ACK;

let mut msg = NetlinkMessage::new(
nl_hdr,
NetlinkPayload::from(RtnlMessage::NewRoute(route_msg)),
);

msg.finalize();
let mut buf = vec![0; msg.header.length as usize];

msg.serialize(&mut buf[..msg.buffer_len()]);

println!(">>> {msg:?}");

socket
.send(&buf, 0)
.expect("failed to send netlink message");

let mut receive_buffer = vec![0; 4096];
let mut offset = 0;

'outer: loop {
let size = socket.recv(&mut &mut receive_buffer[..], 0).unwrap();

loop {
let bytes = &receive_buffer[offset..];
// Parse the message
let rx_packet: NetlinkMessage<RtnlMessage> =
NetlinkMessage::deserialize(bytes).unwrap();

if let NetlinkPayload::Error(err) = rx_packet.payload {
match err.code {
None => {
println!("Done!");
break 'outer;
}
Some(_) => {
eprintln!("Received a netlink error message: {err:?}");
return;
}
}
}

offset += rx_packet.header.length as usize;
if offset == size || rx_packet.header.length == 0 {
offset = 0;
break;
}
}
}
}
5 changes: 5 additions & 0 deletions src/rtnl/route/header.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,11 @@ pub struct RouteFlags: u32 {
const RTM_F_LOOKUP_TABLE = RTM_F_LOOKUP_TABLE;
/// Return the full FIB lookup match (see commit `b61798130f1be5bff08712308126c2d7ebe390ef`)
const RTM_F_FIB_MATCH = RTM_F_FIB_MATCH;

/// Do recursive gateway lookup
const RTNH_F_PERVASIVE = RTNH_F_PERVASIVE as u32;
/// Gateway is forced on link
const RTNH_F_ONLINK = RTNH_F_ONLINK as u32;
}
}

Expand Down