Upgrade crates and fix build
This commit is contained in:
@ -1,9 +1,8 @@
|
|||||||
[workspace]
|
[workspace]
|
||||||
|
|
||||||
members = [
|
members = [
|
||||||
"bgpd",
|
"bgpd",
|
||||||
# "netlink",
|
|
||||||
|
|
||||||
# Tests
|
# Tests
|
||||||
"tests/integration_tests"
|
"tests/integration_tests",
|
||||||
]
|
]
|
||||||
|
resolver = "2"
|
||||||
|
|||||||
@ -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"] }
|
||||||
|
|||||||
@ -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;
|
||||||
|
|||||||
@ -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
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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<()>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user