Cleanup clippy warnings.
Some checks failed
Rust / build (push) Has been cancelled

This commit is contained in:
Rayhaan Jaufeerally
2024-12-08 22:09:00 +00:00
parent cc3842b384
commit b0f2995ed8
18 changed files with 1547 additions and 189 deletions

View File

@ -81,6 +81,8 @@ message AnnouncementRequest {
string peer_name = 1;
Prefix prefix = 2;
repeated string large_communities = 3;
// When set to true inserts the route, when set to false withdraws the route.
bool add = 4;
}
message AnnouncementResponse {}

View File

@ -20,8 +20,8 @@ use crate::rib_manager::RibManager;
use crate::rib_manager::RibSnapshot;
use crate::rib_manager::RouteManagerCommands;
use crate::route_server;
use crate::route_server::route_server::bgp_server_admin_service_server::BgpServerAdminServiceServer;
use crate::route_server::route_server::route_service_server::RouteServiceServer;
use crate::route_server::proto::bgp_server_admin_service_server::BgpServerAdminServiceServer;
use crate::route_server::proto::route_service_server::RouteServiceServer;
use bgp_packet::constants::AddressFamilyIdentifier;
use std::collections::HashMap;
use std::net::Ipv4Addr;

View File

@ -19,7 +19,7 @@ use crate::filter_eval::FilterEvaluator;
use crate::path::path_data::PathData;
use crate::path::path_set::PathSource;
use crate::rib_manager::RouteManagerCommands;
use crate::route_server::route_server::PeerStatus;
use crate::route_server::proto::PeerStatus;
use bgp_packet::capabilities::{
BGPCapability, BGPCapabilityTypeValues, BGPCapabilityValue, BGPOpenOptionTypeValues,
@ -38,10 +38,10 @@ use bgp_packet::messages::NotificationMessage;
use bgp_packet::messages::OpenMessage;
use bgp_packet::messages::UpdateMessage;
use bgp_packet::nlri::NLRI;
use bgp_packet::path_attributes::ASPathAttribute;
use bgp_packet::path_attributes::NextHopPathAttribute;
use bgp_packet::path_attributes::OriginPathAttribute;
use bgp_packet::path_attributes::PathAttribute;
use bgp_packet::path_attributes::{ASPathAttribute, MPUnreachNLRIPathAttribute};
use bgp_packet::path_attributes::{
LargeCommunitiesPathAttribute, LargeCommunitiesPayload, MPReachNLRIPathAttribute,
};
@ -485,7 +485,7 @@ where
};
let mut buf = BytesMut::new();
self.codec.lock().await.encode(bgp_message, &mut buf)?;
conn.write(&buf).await?;
conn.write_all(&buf).await?;
// Update state
self.state = BGPState::OpenSent;
@ -530,8 +530,104 @@ where
}
PeerCommands::Announce(route_update) => match route_update {
RouteUpdate::Announce(announcement) => todo!(),
RouteUpdate::Withdraw(withdrawal) => todo!(),
RouteUpdate::Announce(announcement) => {
// nexthop is not populated in announcement so we set it ourselves here.
let nexthop = if let Some(stream) = &self.tcp_stream {
stream.local_addr()?
} else {
bail!("Cannot send route announcement since tcp stream is closed");
};
let nexthop_attribute: PathAttribute = match nexthop.ip() {
IpAddr::V4(ipv4_addr) => {
// TODO: In the IPv4 case we also need to add the NLRI to the update msg.
PathAttribute::NextHopPathAttribute(NextHopPathAttribute(ipv4_addr))
}
IpAddr::V6(ipv6_addr) => {
PathAttribute::MPReachNLRIPathAttribute(MPReachNLRIPathAttribute {
afi: AddressFamilyIdentifier::Ipv6,
safi: SubsequentAddressFamilyIdentifier::Unicast,
nexthop: ipv6_addr.octets().to_vec(),
nlris: announcement.0.clone(),
})
}
};
let mut path_attributes = vec![
PathAttribute::OriginPathAttribute(announcement.1.origin),
ASPathAttribute::from_asns(announcement.1.as_path.clone()),
nexthop_attribute,
];
for nlri in &announcement.0 {
if !self.filter_evaluator.evaluate_out(
&mut path_attributes,
&announcement.1.as_path,
&nlri,
) {
bail!("Filter rejected NLRI: {}", nlri);
}
}
let update_message = UpdateMessage {
path_attributes,
withdrawn_nlri: Vec::default(),
announced_nlri: Vec::default(),
};
let bgp_message = BGPMessage {
msg_type: UPDATE_MESSAGE,
payload: BGPSubmessage::UpdateMessage(update_message),
};
let mut buf = BytesMut::new();
self.codec
.lock()
.await
.encode(bgp_message, &mut buf)
.map_err(|e| eyre!("failed to encode BGP message: {}", e))?;
if let Some(stream) = self.tcp_stream.as_mut() {
stream
.write(&buf)
.await
.map_err(|e| eyre!("Failed to write msg to peer: {}", e))?;
}
}
RouteUpdate::Withdraw(withdrawal) => {
// Only IPv6 NLRIs are supported for now.
let path_attributes = vec![PathAttribute::MPUnreachNLRIPathAttribute(
MPUnreachNLRIPathAttribute {
afi: AddressFamilyIdentifier::Ipv6,
safi: SubsequentAddressFamilyIdentifier::Unicast,
nlris: withdrawal.prefixes,
},
)];
let update_message = UpdateMessage {
path_attributes,
withdrawn_nlri: vec![],
announced_nlri: vec![],
};
let bgp_message = BGPMessage {
msg_type: UPDATE_MESSAGE,
payload: BGPSubmessage::UpdateMessage(update_message),
};
let mut buf = BytesMut::new();
self.codec
.lock()
.await
.encode(bgp_message, &mut buf)
.map_err(|e| eyre!("failed to encode BGP message: {}", e))?;
if let Some(stream) = self.tcp_stream.as_mut() {
stream
.write(&buf)
.await
.map_err(|e| eyre!("Failed to write msg to peer: {}", e))?;
}
}
},
PeerCommands::MessageFromPeer(msg) => match self.handle_msg(msg).await {
@ -666,7 +762,7 @@ where
self.codec.lock().await.encode(bgp_msg, &mut buf)?;
match self.tcp_stream.as_mut() {
Some(stream) => {
stream.write(&buf).await?;
stream.write_all(&buf).await?;
}
None => warn!("Dropped notification message to peer"),
}
@ -927,7 +1023,7 @@ where
};
let mut buf = BytesMut::new();
self.codec.lock().await.encode(keepalive, &mut buf)?;
conn.write(buf.as_ref()).await?;
conn.write_all(buf.as_ref()).await?;
Ok(())
}
None => Err(std::io::Error::new(

View File

@ -12,29 +12,36 @@
// See the License for the specific language governing permissions and
// limitations under the License.
use crate::data_structures::RouteUpdate;
use crate::data_structures::RouteWithdraw;
use crate::path::path_data::PathData;
use crate::path::path_set::PathSet;
use crate::path::path_set::PathSource;
use crate::peer::PeerCommands;
use crate::rib_manager::RibSnapshot;
use crate::rib_manager::RouteManagerCommands;
use crate::route_server::route_server::bgp_server_admin_service_server::BgpServerAdminService;
use crate::route_server::route_server::route_service_server::RouteService;
use crate::route_server::route_server::AddressFamily;
use crate::route_server::route_server::AnnouncementRequest;
use crate::route_server::route_server::AnnouncementResponse;
use crate::route_server::route_server::DumpPathsRequest;
use crate::route_server::route_server::DumpPathsResponse;
use crate::route_server::route_server::Path;
use crate::route_server::route_server::Prefix;
use crate::route_server::route_server::StreamPathsRequest;
use crate::route_server::proto::bgp_server_admin_service_server::BgpServerAdminService;
use crate::route_server::proto::route_service_server::RouteService;
use crate::route_server::proto::AddressFamily;
use crate::route_server::proto::AnnouncementRequest;
use crate::route_server::proto::AnnouncementResponse;
use crate::route_server::proto::DumpPathsRequest;
use crate::route_server::proto::DumpPathsResponse;
use crate::route_server::proto::Path;
use crate::route_server::proto::Prefix;
use crate::route_server::proto::StreamPathsRequest;
use bgp_packet::constants::AddressFamilyIdentifier;
use route_server::PeerStatusRequest;
use route_server::PeerStatusResponse;
use bgp_packet::nlri::NLRI;
use bgp_packet::path_attributes::OriginPathAttribute;
use chrono::Utc;
use proto::PeerStatusRequest;
use proto::PeerStatusResponse;
use std::collections::HashMap;
use std::net::Ipv4Addr;
use std::net::Ipv6Addr;
use std::sync::Arc;
use tokio::sync::broadcast;
use tokio::sync::mpsc;
use tokio::sync::mpsc::UnboundedSender;
@ -44,7 +51,7 @@ use tonic::Response;
use tonic::Status;
use tracing::{info, warn};
pub mod route_server {
pub mod proto {
tonic::include_proto!("bgpd.grpc");
}
@ -78,11 +85,8 @@ impl RouteServer {
/// Converts a rib_manager::PathSet into the proto format PathSet using the
/// appropriate address family.
fn transform_pathset<A>(
mgr_ps: (u64, PathSet<A>),
address_family: i32,
) -> route_server::PathSet {
let mut proto_pathset = route_server::PathSet {
fn transform_pathset<A>(mgr_ps: (u64, PathSet<A>), address_family: i32) -> proto::PathSet {
let mut proto_pathset = proto::PathSet {
epoch: mgr_ps.0,
prefix: Some(Prefix {
ip_prefix: mgr_ps.1.nlri().prefix.clone(),
@ -151,7 +155,50 @@ impl BgpServerAdminService for RouteServer {
let request = request.get_ref();
if let Some(peer) = self.peer_state_machines.get(&request.peer_name) {
info!("Would make announcement to peer: {}", &request.peer_name);
let prefix = request
.prefix
.as_ref()
.ok_or(Status::invalid_argument("Missing prefix"))?;
let nlri = NLRI {
afi: AddressFamilyIdentifier::Ipv6,
prefix: prefix.ip_prefix.clone(),
prefixlen: prefix.prefix_len as u8,
};
if request.add {
let path_data = PathData {
origin: OriginPathAttribute::IGP,
nexthop: Vec::default(),
path_source: PathSource::LocallyConfigured,
local_pref: 100,
med: 100,
as_path: vec![210036],
path_attributes: Vec::default(),
learn_time: Utc::now(),
};
if let Err(e) = peer.send(PeerCommands::Announce(RouteUpdate::Announce((
vec![nlri],
Arc::new(path_data),
)))) {
warn!("Failed to send announcement to peer: {}", e);
return Err(Status::internal(format!(
"Failed to send message to PeerStateMachine: {}",
e
)));
}
} else {
let update = PeerCommands::Announce(RouteUpdate::Withdraw(RouteWithdraw {
peer_id: Ipv4Addr::new(0, 0, 0, 0),
prefixes: vec![nlri],
}));
if let Err(e) = peer.send(update) {
warn!("Failed to send withdrawal to peer: {}", e);
return Err(Status::internal(format!(
"Failed to send message to PeerStateMachine: {}",
e
)));
}
}
} else {
return Err(Status::invalid_argument(format!(
"No such peer: {}",
@ -189,7 +236,7 @@ impl RouteService for RouteServer {
Ok(result) => {
response.epoch = result.epoch;
for pathset in result.routes {
let mut proto_pathset = route_server::PathSet {
let mut proto_pathset = proto::PathSet {
epoch: result.epoch,
prefix: Some(Prefix {
ip_prefix: pathset.nlri().prefix.clone(),
@ -236,7 +283,7 @@ impl RouteService for RouteServer {
Ok(result) => {
response.epoch = result.epoch;
for pathset in result.routes {
let mut proto_pathset = route_server::PathSet {
let mut proto_pathset = proto::PathSet {
epoch: result.epoch,
prefix: Some(Prefix {
ip_prefix: pathset.nlri().prefix.clone(),
@ -274,7 +321,7 @@ impl RouteService for RouteServer {
}
}
type StreamPathsStream = ReceiverStream<Result<route_server::PathSet, Status>>;
type StreamPathsStream = ReceiverStream<Result<proto::PathSet, Status>>;
async fn stream_paths(
&self,