Upgrade crates and fix build

This commit is contained in:
Rayhaan Jaufeerally
2024-03-04 22:37:08 +01:00
parent a38ff34634
commit 75dbfc319a
5 changed files with 78 additions and 87 deletions

View File

@ -1,9 +1,8 @@
[workspace] [workspace]
members = [ members = [
"bgpd", "bgpd",
# "netlink",
# Tests # Tests
"tests/integration_tests" "tests/integration_tests",
] ]
resolver = "2"

View File

@ -1,16 +1,16 @@
[package] [package]
name = "bgpd"
version = "0.1.0"
authors = ["Rayhaan Jaufeerally <rayhaan@rayhaan.ch>"] authors = ["Rayhaan Jaufeerally <rayhaan@rayhaan.ch>"]
edition = "2021" edition = "2021"
name = "bgpd"
version = "0.1.0"
[[bin]] [[bin]]
name = "bgp_server" name = "bgp_server"
path = "src/main.rs" path = "src/main.rs"
#[[bin]] [[bin]]
#name = "route_client" name = "route_client"
#path = "src/route_client/main.rs" path = "src/route_client/main.rs"
[[bin]] [[bin]]
name = "streamer_cli" name = "streamer_cli"
@ -18,18 +18,24 @@ path = "src/streamer_cli/main.rs"
[dependencies] [dependencies]
anyhow = "1.0.71" anyhow = "1.0.71"
async-trait = "0.1.57"
byteorder = "1.4.3" byteorder = "1.4.3"
bytes = "1.*" bytes = "1.*"
clap = {version = "3.2.8", features = ["cargo", "derive"]} clap = { version = "3.2.8", features = ["cargo", "derive"] }
futures = "0.3" futures = "0.3"
ip_network_table-deps-treebitmap = "0.5.0"
ipnet = "2.3.0" ipnet = "2.3.0"
libc = "0.2.126" libc = "0.2.126"
log = "0.4" log = "0.4"
netlink = "0.1.1"
netlink-packet-route = "0.19.0"
netlink-packet-utils = "0.5.2"
nom = "7.1" nom = "7.1"
prost = "0.8" prost = "0.8"
rtnetlink = "0.14.1"
serde = { version = "1.0", features = ["derive"] } serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0.64" serde_json = "1.0.64"
signal-hook = { version = "0.3.10", features = ["extended-siginfo"] } signal-hook = { version = "0.3.17", features = ["extended-siginfo"] }
signal-hook-tokio = "0.3.0" signal-hook-tokio = "0.3.0"
stderrlog = "0.5.1" stderrlog = "0.5.1"
tokio = { version = "1.13.0", features = ["full"] } tokio = { version = "1.13.0", features = ["full"] }
@ -38,10 +44,7 @@ tokio-util = { version = "0.6.7", features = ["codec"] }
tonic = { version = "0.5", features = ["compression"] } tonic = { version = "0.5", features = ["compression"] }
tracing = "0.1" tracing = "0.1"
tracing-subscriber = { version = "0.3.17", features = ["env-filter"] } tracing-subscriber = { version = "0.3.17", features = ["env-filter"] }
ip_network_table-deps-treebitmap = "0.5.0"
warp = "0.3.5" warp = "0.3.5"
# neli = "0.6.2"
async-trait = "0.1.57"
[build-dependencies] [build-dependencies]
tonic-build = { version = "0.5.1", features = ["prost", "compression"] } tonic-build = { version = "0.5.1", features = ["compression", "prost"] }

View File

@ -1,3 +1,3 @@
pub mod bgp_packet; pub mod bgp_packet;
// pub mod route_client; pub mod route_client;
pub mod server; pub mod server;

View File

@ -1,10 +1,15 @@
use crate::bgp_packet::{constants::AddressFamilyIdentifier, nlri::NLRI}; use crate::bgp_packet::{constants::AddressFamilyIdentifier, nlri::NLRI};
use anyhow::Result; use anyhow::{anyhow, Result};
use async_trait::async_trait; use async_trait::async_trait;
use futures::TryStreamExt; use futures::TryStreamExt;
use netlink::constants::RTN_UNICAST; use netlink_packet_route::route::RouteAddress;
use netlink_packet_route::{rtnl::route::nlas::Nla, RouteHeader}; use netlink_packet_route::route::RouteAttribute;
use netlink_packet_route::{RouteMessage, RTPROT_STATIC}; use netlink_packet_route::route::RouteHeader;
use netlink_packet_route::route::RouteMessage;
use netlink_packet_route::route::RouteProtocol;
use netlink_packet_route::route::RouteType;
use netlink_packet_route::AddressFamily as NetlinkAddressFamily;
use netlink_packet_utils::nla::Nla;
use rtnetlink::IpVersion; use rtnetlink::IpVersion;
use std::net::{IpAddr, Ipv4Addr, Ipv6Addr}; use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
use std::{convert::TryInto, io::ErrorKind}; use std::{convert::TryInto, io::ErrorKind};
@ -29,7 +34,8 @@ impl SouthboundInterface for NetlinkConnector {
let route = self.handle.route(); let route = self.handle.route();
match address_family { match address_family {
AddressFamilyIdentifier::Ipv6 => { AddressFamilyIdentifier::Ipv6 => {
let addr: Ipv6Addr = match prefix.clone().try_into()? { let prefix_len = prefix.prefixlen;
let addr: Ipv6Addr = match prefix.try_into()? {
IpAddr::V6(addr) => addr, IpAddr::V6(addr) => addr,
_ => { _ => {
return Err(anyhow::Error::from(std::io::Error::new( return Err(anyhow::Error::from(std::io::Error::new(
@ -50,7 +56,7 @@ impl SouthboundInterface for NetlinkConnector {
let mut mutation = route let mut mutation = route
.add() .add()
.v6() .v6()
.destination_prefix(addr, prefix.prefixlen) .destination_prefix(addr, prefix_len)
.gateway(gw_addr); .gateway(gw_addr);
if let Some(table_id) = self.table { if let Some(table_id) = self.table {
mutation = mutation.table(table_id.try_into().unwrap()); mutation = mutation.table(table_id.try_into().unwrap());
@ -58,6 +64,7 @@ impl SouthboundInterface for NetlinkConnector {
mutation.execute().await.map_err(|e| anyhow::Error::from(e)) mutation.execute().await.map_err(|e| anyhow::Error::from(e))
} }
AddressFamilyIdentifier::Ipv4 => { AddressFamilyIdentifier::Ipv4 => {
let prefix_len = prefix.prefixlen;
let addr: Ipv4Addr = match prefix.clone().try_into()? { let addr: Ipv4Addr = match prefix.clone().try_into()? {
IpAddr::V4(addr) => addr, IpAddr::V4(addr) => addr,
_ => { _ => {
@ -79,7 +86,7 @@ impl SouthboundInterface for NetlinkConnector {
let mut mutation = route let mut mutation = route
.add() .add()
.v4() .v4()
.destination_prefix(addr, prefix.prefixlen) .destination_prefix(addr, prefix_len)
.gateway(gw_addr); .gateway(gw_addr);
if let Some(table_id) = self.table { if let Some(table_id) = self.table {
mutation = mutation.table(table_id.try_into().unwrap()); mutation = mutation.table(table_id.try_into().unwrap());
@ -90,55 +97,36 @@ impl SouthboundInterface for NetlinkConnector {
} }
async fn route_del(&mut self, prefix: NLRI, nexthop: IpAddr) -> Result<()> { async fn route_del(&mut self, prefix: NLRI, nexthop: IpAddr) -> Result<()> {
let nh_octets = match nexthop {
IpAddr::V6(addr) => addr.octets().to_vec(),
IpAddr::V4(addr) => addr.octets().to_vec(),
};
let rt_handle = self.handle.route(); let rt_handle = self.handle.route();
let address_family = match prefix.afi { let destination = match prefix.afi {
AddressFamilyIdentifier::Ipv4 => netlink_packet_route::rtnl::constants::AF_INET as u8,
AddressFamilyIdentifier::Ipv6 => netlink_packet_route::rtnl::constants::AF_INET6 as u8,
};
let header = RouteHeader {
address_family,
destination_prefix_length: prefix.prefixlen,
table: self.table.unwrap_or(0) as u8,
protocol: RTPROT_STATIC,
kind: RTN_UNICAST,
..Default::default()
};
let mut rt_msg = RouteMessage {
header,
..Default::default()
};
let prefix_octets = match prefix.afi {
AddressFamilyIdentifier::Ipv4 => { AddressFamilyIdentifier::Ipv4 => {
let addr: Ipv4Addr = match prefix.clone().try_into()? { RouteAddress::Inet(prefix.clone().try_into().map_err(|e: String| anyhow!(e))?)
IpAddr::V4(addr) => addr,
_ => {
return Err(anyhow::Error::from(std::io::Error::new(
ErrorKind::InvalidInput,
"Got non-IPv4 address from NLRI",
)))
}
};
addr.octets().to_vec()
} }
AddressFamilyIdentifier::Ipv6 => { AddressFamilyIdentifier::Ipv6 => {
let addr: Ipv6Addr = match prefix.clone().try_into()? { RouteAddress::Inet6(prefix.clone().try_into().map_err(|e: String| anyhow!(e))?)
IpAddr::V6(addr) => addr,
_ => {
return Err(anyhow::Error::from(std::io::Error::new(
ErrorKind::InvalidInput,
"Got non-IPv6 address from NLRI",
)))
} }
}; };
addr.octets().to_vec() let nexthop = match nexthop {
} IpAddr::V4(ipv4) => RouteAddress::Inet(ipv4),
IpAddr::V6(ipv6) => RouteAddress::Inet6(ipv6),
}; };
rt_msg.nlas.push(Nla::Destination(prefix_octets)); let header = RouteHeader {
rt_msg.nlas.push(Nla::Gateway(nh_octets)); address_family: match prefix.afi {
AddressFamilyIdentifier::Ipv4 => NetlinkAddressFamily::Inet,
AddressFamilyIdentifier::Ipv6 => NetlinkAddressFamily::Inet6,
},
destination_prefix_length: prefix.prefixlen,
table: self.table.unwrap_or(0) as u8,
protocol: RouteProtocol::Bgp,
kind: RouteType::Unicast,
..Default::default()
};
let mut rt_msg: RouteMessage = Default::default();
rt_msg.header = header;
rt_msg.attributes = vec![
RouteAttribute::Destination(destination),
RouteAttribute::Gateway(nexthop),
];
rt_handle rt_handle
.del(rt_msg) .del(rt_msg)
.execute() .execute()
@ -165,8 +153,8 @@ impl NetlinkConnector {
}); });
if let Some(table_id) = table { if let Some(table_id) = table {
req.message_mut() req.message_mut()
.nlas .attributes
.push(Nla::Table(table_id.try_into().unwrap())); .push(RouteAttribute::Table(table_id));
} }
req.execute().try_collect().await req.execute().try_collect().await
} }

View File

@ -22,15 +22,16 @@ use log::info;
/// SouthboundInterface provides a uniform API to network forwarding elements /// SouthboundInterface provides a uniform API to network forwarding elements
/// These are devices or targets that perform packet routing and are the end /// These are devices or targets that perform packet routing and are the end
/// consumers of packet routing data. /// consumers of packet routing data.
#[async_trait] #[async_trait]
pub trait SouthboundInterface { pub trait SouthboundInterface {
/// route_add adds a route towards a particular address_family/NLRI via the given nexthop.
async fn route_add( async fn route_add(
&mut self, &mut self,
address_family: AddressFamilyIdentifier, address_family: AddressFamilyIdentifier,
prefix: NLRI, prefix: NLRI,
nexthop: IpAddr, nexthop: IpAddr,
) -> Result<()>; ) -> Result<()>;
/// route_del removes the route towards a particular prefix via a given nexthop.
async fn route_del(&mut self, prefix: NLRI, nexthop: IpAddr) -> Result<()>; async fn route_del(&mut self, prefix: NLRI, nexthop: IpAddr) -> Result<()>;
} }