Skip to content

Commit

Permalink
Merge pull request #31 from holo-routing/upgrade-rtnetlink
Browse files Browse the repository at this point in the history
netlink: upgrade rtnetlink to version 0.14.1
  • Loading branch information
rwestphal committed Sep 17, 2024
2 parents 32fb3f4 + 506c5b9 commit cd6714a
Show file tree
Hide file tree
Showing 5 changed files with 52 additions and 53 deletions.
5 changes: 3 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,8 @@ maplit = "1.0"
md5 = "0.7"
nix = { version = "0.29", features = ["fs", "net", "socket", "uio", "user"] }
netlink-packet-core = "0.7"
netlink-packet-route = "0.17"
netlink-packet-route = "0.19"
netlink-packet-utils = "0.5"
netlink-sys = "0.8"
num-derive = "0.4"
num-traits = "0.2"
Expand All @@ -61,7 +62,7 @@ prefix-trie = { version = "0.4.1", default-features = false, features = ["ipnetw
prost = "0.12"
rand = "0.8.5"
regex = "1.10"
rtnetlink = "0.13"
rtnetlink = "0.14.1"
serde = { version = "1.0", features = ["derive", "rc"] }
serde_json = "1.0"
serde_with = "3.7"
Expand Down
2 changes: 2 additions & 0 deletions holo-interface/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,13 @@ generational-arena.workspace = true
ipnetwork.workspace = true
netlink-packet-route.workspace = true
netlink-packet-core.workspace = true
netlink-packet-utils.workspace = true
netlink-sys.workspace = true
rtnetlink.workspace = true
tokio.workspace = true
tracing.workspace = true
yang3.workspace = true
libc.workspace = true

holo-northbound = { path = "../holo-northbound" }
holo-utils = { path = "../holo-utils" }
Expand Down
77 changes: 39 additions & 38 deletions holo-interface/src/netlink.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,16 @@ use std::net::{Ipv4Addr, Ipv6Addr};
use capctl::caps::CapState;
use futures::channel::mpsc::UnboundedReceiver;
use futures::TryStreamExt;
use holo_utils::ip::IpAddrExt;
use holo_utils::southbound::InterfaceFlags;
use ipnetwork::IpNetwork;
use libc::{RTNLGRP_IPV4_IFADDR, RTNLGRP_IPV6_IFADDR, RTNLGRP_LINK};
use netlink_packet_core::{NetlinkMessage, NetlinkPayload};
use netlink_packet_route::constants::{
AF_INET, AF_INET6, ARPHRD_LOOPBACK, IFF_BROADCAST, IFF_RUNNING,
RTNLGRP_IPV4_IFADDR, RTNLGRP_IPV6_IFADDR, RTNLGRP_LINK,
use netlink_packet_route::address::{AddressAttribute, AddressMessage};
use netlink_packet_route::link::{
LinkAttribute, LinkFlag, LinkLayerType, LinkMessage,
};
use netlink_packet_route::rtnl::RtnlMessage;
use netlink_packet_route::{AddressMessage, LinkMessage};
use netlink_packet_route::RouteNetlinkMessage;
use netlink_sys::{AsyncSocket, SocketAddr};
use rtnetlink::{new_connection, Handle};
use tracing::{error, trace};
Expand All @@ -26,7 +27,7 @@ use crate::interface::Owner;
use crate::Master;

pub type NetlinkMonitor =
UnboundedReceiver<(NetlinkMessage<RtnlMessage>, SocketAddr)>;
UnboundedReceiver<(NetlinkMessage<RouteNetlinkMessage>, SocketAddr)>;

// ===== helper functions =====

Expand All @@ -35,8 +36,6 @@ async fn process_newlink_msg(
msg: LinkMessage,
notify: bool,
) {
use netlink_packet_route::link::nlas::Nla;

trace!(?msg, "received RTM_NEWLINK message");

// Fetch interface attributes.
Expand All @@ -46,20 +45,22 @@ async fn process_newlink_msg(
let mut mac_address: [u8; 6] = [0u8; 6];

let mut flags = InterfaceFlags::empty();
if msg.header.link_layer_type == ARPHRD_LOOPBACK {
if msg.header.link_layer_type == LinkLayerType::Loopback {
flags.insert(InterfaceFlags::LOOPBACK);
}
if msg.header.flags & IFF_RUNNING != 0 {

if msg.header.flags.contains(&LinkFlag::Running) {
flags.insert(InterfaceFlags::OPERATIVE);
}
if msg.header.flags & IFF_BROADCAST != 0 {
flags.insert(InterfaceFlags::BROADCAST);
if msg.header.flags.contains(&LinkFlag::Broadcast) {
flags.insert(InterfaceFlags::BROADCAST)
}
for nla in msg.nlas.into_iter() {

for nla in msg.attributes.into_iter() {
match nla {
Nla::IfName(nla_ifname) => ifname = Some(nla_ifname),
Nla::Mtu(nla_mtu) => mtu = Some(nla_mtu),
Nla::Address(addr) => {
LinkAttribute::IfName(nla_ifname) => ifname = Some(nla_ifname),
LinkAttribute::Mtu(nla_mtu) => mtu = Some(nla_mtu),
LinkAttribute::Address(addr) => {
mac_address = addr.try_into().unwrap_or([0u8; 6]);
}
_ => (),
Expand Down Expand Up @@ -107,16 +108,14 @@ async fn process_dellink_msg(
}

fn process_newaddr_msg(master: &mut Master, msg: AddressMessage, notify: bool) {
use netlink_packet_route::address::nlas::Nla;

trace!(?msg, "received RTM_NEWADDR message");

// Fetch address attributes.
let mut addr = None;
let ifindex = msg.header.index;
for nla in msg.nlas.into_iter() {
for nla in msg.attributes.into_iter() {
match nla {
Nla::Address(nla_addr) => addr = Some(nla_addr),
AddressAttribute::Address(nla_addr) => addr = Some(nla_addr),
_ => (),
}
}
Expand All @@ -125,9 +124,11 @@ fn process_newaddr_msg(master: &mut Master, msg: AddressMessage, notify: bool) {
};

// Parse address.
let Some(addr) =
parse_address(msg.header.family, msg.header.prefix_len, addr)
else {
let Some(addr) = parse_address(
msg.header.family.into(),
msg.header.prefix_len,
addr.bytes(),
) else {
return;
};

Expand All @@ -137,16 +138,14 @@ fn process_newaddr_msg(master: &mut Master, msg: AddressMessage, notify: bool) {
}

fn process_deladdr_msg(master: &mut Master, msg: AddressMessage, notify: bool) {
use netlink_packet_route::address::nlas::Nla;

trace!(?msg, "received RTM_DELADDR message");

// Fetch address attributes.
let mut addr = None;
let ifindex = msg.header.index;
for nla in msg.nlas.into_iter() {
for nla in msg.attributes.into_iter() {
match nla {
Nla::Address(nla_addr) => addr = Some(nla_addr),
AddressAttribute::Address(nla_addr) => addr = Some(nla_addr),
_ => (),
}
}
Expand All @@ -155,9 +154,11 @@ fn process_deladdr_msg(master: &mut Master, msg: AddressMessage, notify: bool) {
};

// Parse address.
let Some(addr) =
parse_address(msg.header.family, msg.header.prefix_len, addr)
else {
let Some(addr) = parse_address(
msg.header.family.into(),
msg.header.prefix_len,
addr.bytes(),
) else {
return;
};

Expand All @@ -171,13 +172,13 @@ fn parse_address(
prefixlen: u8,
bytes: Vec<u8>,
) -> Option<IpNetwork> {
let addr = match family as u16 {
AF_INET => {
let addr = match family as i32 {
libc::AF_INET => {
let mut addr_array: [u8; 4] = [0; 4];
addr_array.copy_from_slice(&bytes);
Ipv4Addr::from(addr_array).into()
}
AF_INET6 => {
libc::AF_INET6 => {
let mut addr_array: [u8; 16] = [0; 16];
addr_array.copy_from_slice(&bytes);
Ipv6Addr::from(addr_array).into()
Expand Down Expand Up @@ -264,20 +265,20 @@ pub(crate) async fn addr_uninstall(

pub(crate) async fn process_msg(
master: &mut Master,
msg: NetlinkMessage<RtnlMessage>,
msg: NetlinkMessage<RouteNetlinkMessage>,
) {
if let NetlinkPayload::InnerMessage(msg) = msg.payload {
match msg {
RtnlMessage::NewLink(msg) => {
RouteNetlinkMessage::NewLink(msg) => {
process_newlink_msg(master, msg, true).await
}
RtnlMessage::DelLink(msg) => {
RouteNetlinkMessage::DelLink(msg) => {
process_dellink_msg(master, msg, true).await
}
RtnlMessage::NewAddress(msg) => {
RouteNetlinkMessage::NewAddress(msg) => {
process_newaddr_msg(master, msg, true)
}
RtnlMessage::DelAddress(msg) => {
RouteNetlinkMessage::DelAddress(msg) => {
process_deladdr_msg(master, msg, true)
}
_ => (),
Expand Down
1 change: 1 addition & 0 deletions holo-routing/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ ipnetwork.workspace = true
prefix-trie.workspace = true
regex.workspace = true
rtnetlink.workspace = true
netlink-packet-route.workspace = true
tokio.workspace = true
tracing.workspace = true
yang3.workspace = true
Expand Down
20 changes: 7 additions & 13 deletions holo-routing/src/netlink.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,25 +11,19 @@ use holo_utils::mpls::Label;
use holo_utils::protocol::Protocol;
use holo_utils::southbound::Nexthop;
use ipnetwork::IpNetwork;
use netlink_packet_route::route::RouteProtocol;
use rtnetlink::{new_connection, Handle, RouteAddRequest};
use tracing::error;

use crate::rib::Route;

// Route protocol types as defined in the rtnetlink.h kernel header.
const NETLINK_PROTO_UNSPEC: u8 = 0;
const NETLINK_PROTO_STATIC: u8 = 4;
const NETLINK_PROTO_BGP: u8 = 186;
const NETLINK_PROTO_OSPF: u8 = 188;
const NETLINK_PROTO_RIP: u8 = 189;

fn netlink_protocol(protocol: Protocol) -> u8 {
fn netlink_protocol(protocol: Protocol) -> RouteProtocol {
match protocol {
Protocol::BGP => NETLINK_PROTO_BGP,
Protocol::OSPFV2 | Protocol::OSPFV3 => NETLINK_PROTO_OSPF,
Protocol::RIPV2 | Protocol::RIPNG => NETLINK_PROTO_RIP,
Protocol::STATIC => NETLINK_PROTO_STATIC,
_ => NETLINK_PROTO_UNSPEC,
Protocol::BGP => RouteProtocol::Bgp,
Protocol::OSPFV2 | Protocol::OSPFV3 => RouteProtocol::Ospf,
Protocol::RIPV2 | Protocol::RIPNG => RouteProtocol::Rip,
Protocol::STATIC => RouteProtocol::Static,
_ => RouteProtocol::Unspec,
}
}

Expand Down

0 comments on commit cd6714a

Please sign in to comment.