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

Rtnetlink version Upgrade #30

Merged
merged 2 commits into from
Sep 17, 2024
Merged
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
5 changes: 3 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,8 @@ maplit = "1.0"
md5 = "0.7"
nix = "0.26"
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 @@ -60,7 +61,7 @@ prefix-trie = { version = "0.4.1", features = ["ipnetwork"] }
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,12 +16,14 @@ 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
regex.workspace = true
rtnetlink.workspace = true
tokio.workspace = true
tracing.workspace = true
yang2.workspace = true
libc.workspace = true

holo-northbound = { path = "../holo-northbound" }
holo-protocol = { path = "../holo-protocol" }
Expand Down
74 changes: 38 additions & 36 deletions holo-interface/src/netlink.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,24 +11,27 @@ 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_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, MACVLAN_MODE_BRIDGE};
use netlink_packet_route::RouteNetlinkMessage;
use netlink_sys::{AsyncSocket, SocketAddr};
use rtnetlink::{new_connection, Handle};
use tracing::{error, trace};

use crate::interface::Owner;
use crate::Master;

pub const MACVLAN_MODE_BRIDGE: u32 = 4;

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

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

Expand All @@ -37,8 +40,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 @@ -48,17 +49,18 @@ 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);
}
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 @@ -106,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 @@ -124,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 @@ -136,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 @@ -154,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 @@ -170,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 @@ -304,20 +306,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
yang2.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
Loading