From b0f2995ed8b1010bd68ae77ff48f260412a7f40f Mon Sep 17 00:00:00 2001 From: Rayhaan Jaufeerally Date: Sun, 8 Dec 2024 22:09:00 +0000 Subject: [PATCH] Cleanup clippy warnings. --- bin/Cargo.toml | 5 + bin/src/api_server/main.rs | 124 ++ configs/bgplab.json | 1000 +++++++++++++++++ crates/bgp_packet/src/capabilities.rs | 81 +- crates/bgp_packet/src/constants.rs | 48 +- crates/bgp_packet/src/messages.rs | 36 +- crates/bgp_packet/src/nlri.rs | 29 +- crates/bgp_packet/src/path_attributes.rs | 66 +- crates/bgp_packet/src/traits.rs | 9 +- crates/route_client/proto/route_service.proto | 2 + crates/route_client/src/connector.rs | 66 ++ crates/route_client/src/lib.rs | 1 + .../route_client/src/southbound_interface.rs | 12 +- crates/server/proto/route_service.proto | 2 + crates/server/src/bgp_server.rs | 4 +- crates/server/src/peer.rs | 110 +- crates/server/src/route_server.rs | 91 +- .../integration_tests/tests/basic_startup.rs | 50 +- 18 files changed, 1547 insertions(+), 189 deletions(-) create mode 100644 bin/src/api_server/main.rs create mode 100644 configs/bgplab.json create mode 100644 crates/route_client/src/connector.rs diff --git a/bin/Cargo.toml b/bin/Cargo.toml index 69686a4..d5a3069 100644 --- a/bin/Cargo.toml +++ b/bin/Cargo.toml @@ -8,6 +8,7 @@ rust-version.workspace = true version.workspace = true [dependencies] +axum = "0.7.7" bgp_packet.workspace = true bgp_server.workspace = true clap.workspace = true @@ -33,3 +34,7 @@ path = "src/client/main.rs" [[bin]] name = "util" path = "src/util/main.rs" + +[[bin]] +name = "api_server" +path = "src/api_server/main.rs" diff --git a/bin/src/api_server/main.rs b/bin/src/api_server/main.rs new file mode 100644 index 0000000..ac356f3 --- /dev/null +++ b/bin/src/api_server/main.rs @@ -0,0 +1,124 @@ +use std::sync::Arc; + +use axum::extract::{Path, State}; +use axum::http::StatusCode; +use axum::routing::post; +use axum::Router; +use bgp_packet::nlri::NLRI; +use clap::{Parser, Subcommand}; +use eyre::{bail, Result}; +use route_client::connector::Connector; +use tokio::sync::Mutex; +use tracing::info; + +use tracing_subscriber::layer::SubscriberExt; +use tracing_subscriber::util::SubscriberInitExt; +use tracing_subscriber::EnvFilter; + +#[derive(Parser)] +#[clap( + author = "Rayhaan Jaufeerally ", + version = "0.1", + about = "API Server" +)] +struct Cli { + #[clap(subcommand)] + command: Option, +} + +#[derive(Subcommand)] +enum Commands { + /// Run runs the API server connected to a given gRPC backend. + Run { + /// The route server gRPC backend. + backend: String, + }, +} + +struct AppState { + pub connector: Connector, +} + +async fn handle_announce( + State(state): State>>, + Path((prefix, prefixlen)): Path<(String, u8)>, +) -> Result<(StatusCode, String), (StatusCode, String)> { + state + .lock() + .await + .connector + .send_announce( + "pr01_rue_rayhaan_net".to_owned(), + NLRI::try_from(format!("{}/{}", prefix, prefixlen).as_str()).map_err(|e| { + ( + StatusCode::BAD_REQUEST, + format!("failed to parse NLRI: {}", e), + ) + })?, + ) + .await + .map_err(|e| { + ( + StatusCode::INTERNAL_SERVER_ERROR, + format!("failed to make RPC to backend: {}", e), + ) + })?; + Ok((StatusCode::OK, "Success".to_owned())) +} + +async fn handle_withdraw( + State(state): State>>, + Path((prefix, prefixlen)): Path<(String, u8)>, +) -> Result<(StatusCode, String), (StatusCode, String)> { + state + .lock() + .await + .connector + .send_withdraw( + "pr01_rue_rayhaan_net".to_owned(), + NLRI::try_from(format!("{}/{}", prefix, prefixlen).as_str()).map_err(|e| { + ( + StatusCode::BAD_REQUEST, + format!("failed to parse NLRI: {}", e), + ) + })?, + ) + .await + .map_err(|e| { + ( + StatusCode::INTERNAL_SERVER_ERROR, + format!("failed to make RPC to backend: {}", e), + ) + })?; + Ok((StatusCode::OK, "Success".to_owned())) +} + +#[tokio::main] +async fn main() -> Result<()> { + let args = Cli::parse(); + + tracing_subscriber::registry() + .with(tracing_subscriber::fmt::layer()) + .with(EnvFilter::from_default_env()) + .init(); + + info!("Starting API Server"); + + match args.command { + Some(Commands::Run { backend }) => { + let connector = Connector::new(backend).await?; + let app = Router::new() + .route("/announce/:prefix/:prefixlen", post(handle_announce)) + .route("/withdraw/:prefix/:prefixlen", post(handle_withdraw)) + .with_state(Arc::new(Mutex::new(AppState { connector }))); + + let listener = tokio::net::TcpListener::bind("localhost:8179") + .await + .unwrap(); + axum::serve(listener, app).await.unwrap(); + } + None => bail!("A subcommand must be specified."), + }; + + Ok(()) +} diff --git a/configs/bgplab.json b/configs/bgplab.json new file mode 100644 index 0000000..c359096 --- /dev/null +++ b/configs/bgplab.json @@ -0,0 +1,1000 @@ +{ + "identifier": "193.36.105.11", + "asn": 210036, + "hold_time": 180, + "listen_addrs": [ + "[::]:179" + ], + "grpc_addr": "0.0.0.0:9179", + "peers": [ + { + "name": "pr01_rue_rayhaan_net", + "ip": "2a0d:d747:100::", + "asn": 210036, + "afi": "Ipv6", + "safi": "Unicast", + "local_pref": 50, + "announcements": [], + "filter_in": [ + [ + { + "nlri": "::/0", + "origin_asn": null, + "large_community": null + }, + "Reject" + ], + [ + { + "nlri": null, + "origin_asn": null, + "large_community": null + }, + "Accept" + ] + ], + "filter_out": [ + [ + { + "nlri": "2a0d:d740:c001::/48", + "origin_asn": null, + "large_community": null + }, + "Accept" + ], + [ + { + "nlri": "2a0d:d740:c002::/48", + "origin_asn": null, + "large_community": null + }, + "Accept" + ], + [ + { + "nlri": "2a0d:d740:c003::/48", + "origin_asn": null, + "large_community": null + }, + "Accept" + ], + [ + { + "nlri": "2a0d:d740:c004::/48", + "origin_asn": null, + "large_community": null + }, + "Accept" + ], + [ + { + "nlri": "2a0d:d740:c005::/48", + "origin_asn": null, + "large_community": null + }, + "Accept" + ], + [ + { + "nlri": "2a0d:d740:c006::/48", + "origin_asn": null, + "large_community": null + }, + "Accept" + ], + [ + { + "nlri": "2a0d:d740:c007::/48", + "origin_asn": null, + "large_community": null + }, + "Accept" + ], + [ + { + "nlri": "2a0d:d740:c008::/48", + "origin_asn": null, + "large_community": null + }, + "Accept" + ], + [ + { + "nlri": "2a0d:d740:c009::/48", + "origin_asn": null, + "large_community": null + }, + "Accept" + ], + [ + { + "nlri": "2a0d:d740:c010::/48", + "origin_asn": null, + "large_community": null + }, + "Accept" + ], + [ + { + "nlri": "2a0d:d740:c011::/48", + "origin_asn": null, + "large_community": null + }, + "Accept" + ], + [ + { + "nlri": "2a0d:d740:c012::/48", + "origin_asn": null, + "large_community": null + }, + "Accept" + ], + [ + { + "nlri": "2a0d:d740:c013::/48", + "origin_asn": null, + "large_community": null + }, + "Accept" + ], + [ + { + "nlri": "2a0d:d740:c014::/48", + "origin_asn": null, + "large_community": null + }, + "Accept" + ], + [ + { + "nlri": "2a0d:d740:c015::/48", + "origin_asn": null, + "large_community": null + }, + "Accept" + ], + [ + { + "nlri": "2a0d:d740:c016::/48", + "origin_asn": null, + "large_community": null + }, + "Accept" + ], + [ + { + "nlri": "2a0d:d740:c017::/48", + "origin_asn": null, + "large_community": null + }, + "Accept" + ], + [ + { + "nlri": "2a0d:d740:c018::/48", + "origin_asn": null, + "large_community": null + }, + "Accept" + ], + [ + { + "nlri": "2a0d:d740:c019::/48", + "origin_asn": null, + "large_community": null + }, + "Accept" + ], + [ + { + "nlri": "2a0d:d740:c020::/48", + "origin_asn": null, + "large_community": null + }, + "Accept" + ], + [ + { + "nlri": "2a0d:d740:c021::/48", + "origin_asn": null, + "large_community": null + }, + "Accept" + ], + [ + { + "nlri": "2a0d:d740:c022::/48", + "origin_asn": null, + "large_community": null + }, + "Accept" + ], + [ + { + "nlri": "2a0d:d740:c023::/48", + "origin_asn": null, + "large_community": null + }, + "Accept" + ], + [ + { + "nlri": "2a0d:d740:c024::/48", + "origin_asn": null, + "large_community": null + }, + "Accept" + ], + [ + { + "nlri": "2a0d:d740:c025::/48", + "origin_asn": null, + "large_community": null + }, + "Accept" + ], + [ + { + "nlri": "2a0d:d740:c026::/48", + "origin_asn": null, + "large_community": null + }, + "Accept" + ], + [ + { + "nlri": "2a0d:d740:c027::/48", + "origin_asn": null, + "large_community": null + }, + "Accept" + ], + [ + { + "nlri": "2a0d:d740:c028::/48", + "origin_asn": null, + "large_community": null + }, + "Accept" + ], + [ + { + "nlri": "2a0d:d740:c029::/48", + "origin_asn": null, + "large_community": null + }, + "Accept" + ], + [ + { + "nlri": "2a0d:d740:c030::/48", + "origin_asn": null, + "large_community": null + }, + "Accept" + ], + [ + { + "nlri": "2a0d:d740:c031::/48", + "origin_asn": null, + "large_community": null + }, + "Accept" + ], + [ + { + "nlri": "2a0d:d740:c032::/48", + "origin_asn": null, + "large_community": null + }, + "Accept" + ], + [ + { + "nlri": "2a0d:d740:c033::/48", + "origin_asn": null, + "large_community": null + }, + "Accept" + ], + [ + { + "nlri": "2a0d:d740:c034::/48", + "origin_asn": null, + "large_community": null + }, + "Accept" + ], + [ + { + "nlri": "2a0d:d740:c035::/48", + "origin_asn": null, + "large_community": null + }, + "Accept" + ], + [ + { + "nlri": "2a0d:d740:c036::/48", + "origin_asn": null, + "large_community": null + }, + "Accept" + ], + [ + { + "nlri": "2a0d:d740:c037::/48", + "origin_asn": null, + "large_community": null + }, + "Accept" + ], + [ + { + "nlri": "2a0d:d740:c038::/48", + "origin_asn": null, + "large_community": null + }, + "Accept" + ], + [ + { + "nlri": "2a0d:d740:c039::/48", + "origin_asn": null, + "large_community": null + }, + "Accept" + ], + [ + { + "nlri": "2a0d:d740:c040::/48", + "origin_asn": null, + "large_community": null + }, + "Accept" + ], + [ + { + "nlri": "2a0d:d740:c041::/48", + "origin_asn": null, + "large_community": null + }, + "Accept" + ], + [ + { + "nlri": "2a0d:d740:c042::/48", + "origin_asn": null, + "large_community": null + }, + "Accept" + ], + [ + { + "nlri": "2a0d:d740:c043::/48", + "origin_asn": null, + "large_community": null + }, + "Accept" + ], + [ + { + "nlri": "2a0d:d740:c044::/48", + "origin_asn": null, + "large_community": null + }, + "Accept" + ], + [ + { + "nlri": "2a0d:d740:c045::/48", + "origin_asn": null, + "large_community": null + }, + "Accept" + ], + [ + { + "nlri": "2a0d:d740:c046::/48", + "origin_asn": null, + "large_community": null + }, + "Accept" + ], + [ + { + "nlri": "2a0d:d740:c047::/48", + "origin_asn": null, + "large_community": null + }, + "Accept" + ], + [ + { + "nlri": "2a0d:d740:c048::/48", + "origin_asn": null, + "large_community": null + }, + "Accept" + ], + [ + { + "nlri": "2a0d:d740:c049::/48", + "origin_asn": null, + "large_community": null + }, + "Accept" + ], + [ + { + "nlri": "2a0d:d740:c050::/48", + "origin_asn": null, + "large_community": null + }, + "Accept" + ], + [ + { + "nlri": "2a0d:d740:c051::/48", + "origin_asn": null, + "large_community": null + }, + "Accept" + ], + [ + { + "nlri": "2a0d:d740:c052::/48", + "origin_asn": null, + "large_community": null + }, + "Accept" + ], + [ + { + "nlri": "2a0d:d740:c053::/48", + "origin_asn": null, + "large_community": null + }, + "Accept" + ], + [ + { + "nlri": "2a0d:d740:c054::/48", + "origin_asn": null, + "large_community": null + }, + "Accept" + ], + [ + { + "nlri": "2a0d:d740:c055::/48", + "origin_asn": null, + "large_community": null + }, + "Accept" + ], + [ + { + "nlri": "2a0d:d740:c056::/48", + "origin_asn": null, + "large_community": null + }, + "Accept" + ], + [ + { + "nlri": "2a0d:d740:c057::/48", + "origin_asn": null, + "large_community": null + }, + "Accept" + ], + [ + { + "nlri": "2a0d:d740:c058::/48", + "origin_asn": null, + "large_community": null + }, + "Accept" + ], + [ + { + "nlri": "2a0d:d740:c059::/48", + "origin_asn": null, + "large_community": null + }, + "Accept" + ], + [ + { + "nlri": "2a0d:d740:c060::/48", + "origin_asn": null, + "large_community": null + }, + "Accept" + ], + [ + { + "nlri": "2a0d:d740:c061::/48", + "origin_asn": null, + "large_community": null + }, + "Accept" + ], + [ + { + "nlri": "2a0d:d740:c062::/48", + "origin_asn": null, + "large_community": null + }, + "Accept" + ], + [ + { + "nlri": "2a0d:d740:c063::/48", + "origin_asn": null, + "large_community": null + }, + "Accept" + ], + [ + { + "nlri": "2a0d:d740:c064::/48", + "origin_asn": null, + "large_community": null + }, + "Accept" + ], + [ + { + "nlri": "2a0d:d740:c065::/48", + "origin_asn": null, + "large_community": null + }, + "Accept" + ], + [ + { + "nlri": "2a0d:d740:c066::/48", + "origin_asn": null, + "large_community": null + }, + "Accept" + ], + [ + { + "nlri": "2a0d:d740:c067::/48", + "origin_asn": null, + "large_community": null + }, + "Accept" + ], + [ + { + "nlri": "2a0d:d740:c068::/48", + "origin_asn": null, + "large_community": null + }, + "Accept" + ], + [ + { + "nlri": "2a0d:d740:c069::/48", + "origin_asn": null, + "large_community": null + }, + "Accept" + ], + [ + { + "nlri": "2a0d:d740:c070::/48", + "origin_asn": null, + "large_community": null + }, + "Accept" + ], + [ + { + "nlri": "2a0d:d740:c071::/48", + "origin_asn": null, + "large_community": null + }, + "Accept" + ], + [ + { + "nlri": "2a0d:d740:c072::/48", + "origin_asn": null, + "large_community": null + }, + "Accept" + ], + [ + { + "nlri": "2a0d:d740:c073::/48", + "origin_asn": null, + "large_community": null + }, + "Accept" + ], + [ + { + "nlri": "2a0d:d740:c074::/48", + "origin_asn": null, + "large_community": null + }, + "Accept" + ], + [ + { + "nlri": "2a0d:d740:c075::/48", + "origin_asn": null, + "large_community": null + }, + "Accept" + ], + [ + { + "nlri": "2a0d:d740:c076::/48", + "origin_asn": null, + "large_community": null + }, + "Accept" + ], + [ + { + "nlri": "2a0d:d740:c077::/48", + "origin_asn": null, + "large_community": null + }, + "Accept" + ], + [ + { + "nlri": "2a0d:d740:c078::/48", + "origin_asn": null, + "large_community": null + }, + "Accept" + ], + [ + { + "nlri": "2a0d:d740:c079::/48", + "origin_asn": null, + "large_community": null + }, + "Accept" + ], + [ + { + "nlri": "2a0d:d740:c080::/48", + "origin_asn": null, + "large_community": null + }, + "Accept" + ], + [ + { + "nlri": "2a0d:d740:c081::/48", + "origin_asn": null, + "large_community": null + }, + "Accept" + ], + [ + { + "nlri": "2a0d:d740:c082::/48", + "origin_asn": null, + "large_community": null + }, + "Accept" + ], + [ + { + "nlri": "2a0d:d740:c083::/48", + "origin_asn": null, + "large_community": null + }, + "Accept" + ], + [ + { + "nlri": "2a0d:d740:c084::/48", + "origin_asn": null, + "large_community": null + }, + "Accept" + ], + [ + { + "nlri": "2a0d:d740:c085::/48", + "origin_asn": null, + "large_community": null + }, + "Accept" + ], + [ + { + "nlri": "2a0d:d740:c086::/48", + "origin_asn": null, + "large_community": null + }, + "Accept" + ], + [ + { + "nlri": "2a0d:d740:c087::/48", + "origin_asn": null, + "large_community": null + }, + "Accept" + ], + [ + { + "nlri": "2a0d:d740:c088::/48", + "origin_asn": null, + "large_community": null + }, + "Accept" + ], + [ + { + "nlri": "2a0d:d740:c089::/48", + "origin_asn": null, + "large_community": null + }, + "Accept" + ], + [ + { + "nlri": "2a0d:d740:c090::/48", + "origin_asn": null, + "large_community": null + }, + "Accept" + ], + [ + { + "nlri": "2a0d:d740:c091::/48", + "origin_asn": null, + "large_community": null + }, + "Accept" + ], + [ + { + "nlri": "2a0d:d740:c092::/48", + "origin_asn": null, + "large_community": null + }, + "Accept" + ], + [ + { + "nlri": "2a0d:d740:c093::/48", + "origin_asn": null, + "large_community": null + }, + "Accept" + ], + [ + { + "nlri": "2a0d:d740:c094::/48", + "origin_asn": null, + "large_community": null + }, + "Accept" + ], + [ + { + "nlri": "2a0d:d740:c095::/48", + "origin_asn": null, + "large_community": null + }, + "Accept" + ], + [ + { + "nlri": "2a0d:d740:c096::/48", + "origin_asn": null, + "large_community": null + }, + "Accept" + ], + [ + { + "nlri": "2a0d:d740:c097::/48", + "origin_asn": null, + "large_community": null + }, + "Accept" + ], + [ + { + "nlri": "2a0d:d740:c098::/48", + "origin_asn": null, + "large_community": null + }, + "Accept" + ], + [ + { + "nlri": "2a0d:d740:c099::/48", + "origin_asn": null, + "large_community": null + }, + "Accept" + ], + [ + { + "nlri": "2a0d:d740:c100::/48", + "origin_asn": null, + "large_community": null + }, + "Accept" + ], + [ + { + "nlri": "2a0d:d740:c101::/48", + "origin_asn": null, + "large_community": null + }, + "Accept" + ], + [ + { + "nlri": "2a0d:d740:c102::/48", + "origin_asn": null, + "large_community": null + }, + "Accept" + ], + [ + { + "nlri": "2a0d:d740:c103::/48", + "origin_asn": null, + "large_community": null + }, + "Accept" + ], + [ + { + "nlri": "2a0d:d740:c104::/48", + "origin_asn": null, + "large_community": null + }, + "Accept" + ], + [ + { + "nlri": "2a0d:d740:c105::/48", + "origin_asn": null, + "large_community": null + }, + "Accept" + ], + [ + { + "nlri": "2a0d:d740:c106::/48", + "origin_asn": null, + "large_community": null + }, + "Accept" + ], + [ + { + "nlri": "2a0d:d740:c107::/48", + "origin_asn": null, + "large_community": null + }, + "Accept" + ], + [ + { + "nlri": "2a0d:d740:c108::/48", + "origin_asn": null, + "large_community": null + }, + "Accept" + ], + [ + { + "nlri": "2a0d:d740:c109::/48", + "origin_asn": null, + "large_community": null + }, + "Accept" + ], + [ + { + "nlri": "2a0d:d740:c110::/48", + "origin_asn": null, + "large_community": null + }, + "Accept" + ], + [ + { + "nlri": "2a0d:d740:c111::/48", + "origin_asn": null, + "large_community": null + }, + "Accept" + ], + [ + { + "nlri": "2a0d:d740:c112::/48", + "origin_asn": null, + "large_community": null + }, + "Accept" + ], + [ + { + "nlri": "2a0d:d740:c113::/48", + "origin_asn": null, + "large_community": null + }, + "Accept" + ], + [ + { + "nlri": "2a0d:d740:c114::/48", + "origin_asn": null, + "large_community": null + }, + "Accept" + ], + [ + { + "nlri": "2a0d:d740:c115::/48", + "origin_asn": null, + "large_community": null + }, + "Accept" + ], + [ + { + "nlri": "2a0d:d740:c116::/48", + "origin_asn": null, + "large_community": null + }, + "Accept" + ], + [ + { + "nlri": "2a0d:d740:c117::/48", + "origin_asn": null, + "large_community": null + }, + "Accept" + ], + [ + { + "nlri": "2a0d:d740:c118::/48", + "origin_asn": null, + "large_community": null + }, + "Accept" + ], + [ + { + "nlri": "2a0d:d740:c119::/48", + "origin_asn": null, + "large_community": null + }, + "Accept" + ], + [ + { + "nlri": null, + "origin_asn": null, + "large_community": null + }, + "Reject" + ] + ] + } + ] +} \ No newline at end of file diff --git a/crates/bgp_packet/src/capabilities.rs b/crates/bgp_packet/src/capabilities.rs index c2f94ea..63ca4ed 100644 --- a/crates/bgp_packet/src/capabilities.rs +++ b/crates/bgp_packet/src/capabilities.rs @@ -23,6 +23,7 @@ use nom::number::complete::{be_u16, be_u8}; use nom::Err::Failure; use nom::IResult; use std::fmt; +use std::fmt::Display; /// BGPOpenOptionType represents the option types in the Open message. #[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Debug, Hash)] @@ -34,9 +35,9 @@ impl BGPOpenOptionType { } } -impl Into for BGPOpenOptionType { - fn into(self) -> u8 { - self.0 +impl From for u8 { + fn from(val: BGPOpenOptionType) -> Self { + val.0 } } @@ -95,14 +96,12 @@ impl WritablePacket for OpenOption { } fn wire_len(&self, ctx: &ParserContext) -> Result { match &self.oval { - OpenOptions::Capabilities(c) => { - return Ok(2 + c.wire_len(ctx)?); - } + OpenOptions::Capabilities(c) => Ok(2 + c.wire_len(ctx)?), } } } -impl fmt::Display for OpenOption { +impl Display for OpenOption { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "OpenOption: {}", self.oval) } @@ -113,11 +112,11 @@ pub enum OpenOptions { Capabilities(OpenOptionCapabilities), } -impl fmt::Display for OpenOptions { +impl Display for OpenOptions { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - return match &self { + match &self { OpenOptions::Capabilities(c) => write!(f, "Capabilities: {}", c), - }; + } } } @@ -137,7 +136,7 @@ impl ReadablePacket for OpenOptionCapabilities { be_u8, nom::multi::many0(|i| BGPCapability::from_wire(ctx, i)), )(buf)?; - return IResult::Ok((buf, OpenOptionCapabilities { caps })); + IResult::Ok((buf, OpenOptionCapabilities { caps })) } } @@ -161,7 +160,7 @@ impl WritablePacket for OpenOptionCapabilities { } } -impl fmt::Display for OpenOptionCapabilities { +impl Display for OpenOptionCapabilities { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "Capabilities: [")?; for cap in &self.caps { @@ -181,9 +180,9 @@ impl BGPCapabilityType { } } -impl Into for BGPCapabilityType { - fn into(self) -> u8 { - return self.0; +impl From for u8 { + fn from(val: BGPCapabilityType) -> Self { + val.0 } } @@ -306,17 +305,17 @@ impl WritablePacket for BGPCapability { } fn wire_len(&self, ctx: &ParserContext) -> Result { // BGPCapabilityType(u8) + cap_len(u8) + val - return match &self.val { + match &self.val { BGPCapabilityValue::FourByteASN(v) => Ok(2 + v.wire_len(ctx)?), BGPCapabilityValue::Multiprotocol(v) => Ok(2 + v.wire_len(ctx)?), BGPCapabilityValue::RouteRefresh(v) => Ok(2 + v.wire_len(ctx)?), BGPCapabilityValue::GracefulRestart(v) => Ok(2 + v.wire_len(ctx)?), BGPCapabilityValue::UnknownCapability(v) => Ok(2 + v.wire_len(ctx)?), - }; + } } } -impl fmt::Display for BGPCapability { +impl Display for BGPCapability { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { std::fmt::Display::fmt(&self.val, f) } @@ -331,7 +330,7 @@ pub enum BGPCapabilityValue { UnknownCapability(UnknownCapability), } -impl fmt::Display for BGPCapabilityValue { +impl Display for BGPCapabilityValue { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match &self { BGPCapabilityValue::FourByteASN(v) => std::fmt::Display::fmt(v, f), @@ -379,7 +378,7 @@ impl WritablePacket for UnknownCapability { } } -impl fmt::Display for UnknownCapability { +impl Display for UnknownCapability { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "UnknownCapability type: {}", self.cap_code) } @@ -403,7 +402,7 @@ impl ReadablePacket for FourByteASNCapability { buf: &'a [u8], ) -> IResult<&'a [u8], Self, BGPParserError<&'a [u8]>> { let (buf, asn) = nom::combinator::complete(nom::number::complete::be_u32)(buf)?; - return IResult::Ok((buf, FourByteASNCapability::new(asn))); + IResult::Ok((buf, FourByteASNCapability::new(asn))) } } @@ -418,7 +417,7 @@ impl WritablePacket for FourByteASNCapability { } } -impl fmt::Display for FourByteASNCapability { +impl Display for FourByteASNCapability { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "FourByteASN: asn: {}", self.asn) } @@ -445,17 +444,12 @@ impl ReadablePacket for MultiprotocolCapability { ctx: &ParserContext, buf: &'a [u8], ) -> IResult<&'a [u8], MultiprotocolCapability, BGPParserError<&'a [u8]>> { - let (buf, (afi_raw, _, safi_raw)) = nom::combinator::complete(nom::sequence::tuple(( + let (buf, (afi, _, safi)) = nom::combinator::complete(nom::sequence::tuple(( |i| AddressFamilyIdentifier::from_wire(ctx, i), nom::bytes::complete::take(1u8), |i| SubsequentAddressFamilyIdentifier::from_wire(ctx, i), )))(buf)?; - let afi = AddressFamilyIdentifier::try_from(afi_raw) - .map_err(|e| nom::Err::Error(BGPParserError::CustomText(e.to_string())))?; - let safi = SubsequentAddressFamilyIdentifier::try_from(safi_raw) - .map_err(|e| nom::Err::Error(BGPParserError::CustomText(e.to_string())))?; - IResult::Ok((buf, MultiprotocolCapability::new(afi, safi))) } } @@ -473,7 +467,7 @@ impl WritablePacket for MultiprotocolCapability { } } -impl fmt::Display for MultiprotocolCapability { +impl Display for MultiprotocolCapability { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "MultiprotocolCapbility: [ {} {} ]", self.afi, self.safi,) } @@ -501,7 +495,7 @@ impl ReadablePacket for RouteRefreshCapability { } } -impl fmt::Display for RouteRefreshCapability { +impl Display for RouteRefreshCapability { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "RouteRefreshCapability") } @@ -548,7 +542,7 @@ impl WritablePacket for GracefulRestartPayload { fn to_wire(&self, _: &ParserContext) -> Result, &'static str> { let afi: u16 = self.afi.into(); let mut res = vec![0u8; 2]; - byteorder::NetworkEndian::write_u16(res.as_mut(), afi.into()); + byteorder::NetworkEndian::write_u16(res.as_mut(), afi); res.push(self.safi.into()); res.push(if self.af_flags { 0x80 } else { 0 }); Ok(res) @@ -558,7 +552,7 @@ impl WritablePacket for GracefulRestartPayload { } } -impl fmt::Display for GracefulRestartPayload { +impl Display for GracefulRestartPayload { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!( f, @@ -604,7 +598,7 @@ impl WritablePacket for GracefulRestartCapability { } } -impl fmt::Display for GracefulRestartCapability { +impl Display for GracefulRestartCapability { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "GracefulRestartCapability: [")?; for value in &self.payloads { @@ -630,14 +624,13 @@ impl WritablePacket for ExtendedNextHopEncodingCapability { Ok(self .afi_safi_nhafi .iter() - .map(|e| { + .flat_map(|e| { Into::>::into(e.0) .into_iter() - .chain(vec![0x00, Into::::into(e.1)].into_iter()) - .chain(Into::>::into(e.2).into_iter()) + .chain(vec![0x00, Into::::into(e.1)]) + .chain(Into::>::into(e.2)) .collect::>() }) - .flatten() .collect::>()) } @@ -672,7 +665,7 @@ impl ReadablePacket for ExtendedNextHopEncodingCapability { } } -impl fmt::Display for ExtendedNextHopEncodingCapability { +impl Display for ExtendedNextHopEncodingCapability { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "ExtendednextHopEncodingCapability [")?; for entry in &self.afi_safi_nhafi { @@ -698,7 +691,9 @@ mod tests { #[test] fn test_four_byte_asn_capability() { let bytes: &[u8] = &[0x41, 0x04, 0x00, 0x00, 0x00, 0x2a]; - let ctx = &ParserContext::new().four_octet_asn(true).nlri_mode(Ipv6); + let ctx = &ParserContext::default() + .four_octet_asn(true) + .nlri_mode(Ipv6); let (buf, result) = BGPCapability::from_wire(ctx, bytes).unwrap(); assert_eq!( result, @@ -716,7 +711,9 @@ mod tests { 0x02, 0x06, 0x01, 0x04, 0x00, 0x01, 0x00, 0x01, 0x02, 0x02, 0x80, 0x00, 0x02, 0x02, 0x02, 0x00, 0x02, 0x02, 0x46, 0x00, 0x02, 0x06, 0x41, 0x04, 0x00, 0x00, 0x00, 0x2a, ]; - let ctx = &ParserContext::new().four_octet_asn(true).nlri_mode(Ipv6); + let ctx = &ParserContext::default() + .four_octet_asn(true) + .nlri_mode(Ipv6); let (_buf, result) = nom::multi::many0(|buf: &'a [u8]| OpenOption::from_wire(ctx, buf))(option_bytes) .unwrap(); @@ -728,7 +725,9 @@ mod tests { #[test] fn test_extended_next_hop_encoding_capability() { let bytes: Vec = vec![0x00, 0x01, 0x00, 0x01, 0x00, 0x02]; - let ctx = &ParserContext::new().four_octet_asn(true).nlri_mode(Ipv6); + let ctx = &ParserContext::default() + .four_octet_asn(true) + .nlri_mode(Ipv6); let (_, cap) = ExtendedNextHopEncodingCapability::from_wire(ctx, &bytes).unwrap(); let expected_str = diff --git a/crates/bgp_packet/src/constants.rs b/crates/bgp_packet/src/constants.rs index cbba71e..c495262 100644 --- a/crates/bgp_packet/src/constants.rs +++ b/crates/bgp_packet/src/constants.rs @@ -27,11 +27,11 @@ pub enum AddressFamilyIdentifier { Ipv6, } -impl Into for AddressFamilyIdentifier { - fn into(self) -> u16 { - match self { - Self::Ipv4 => 1, - Self::Ipv6 => 2, +impl From for u16 { + fn from(val: AddressFamilyIdentifier) -> Self { + match val { + AddressFamilyIdentifier::Ipv4 => 1, + AddressFamilyIdentifier::Ipv6 => 2, } } } @@ -50,28 +50,28 @@ impl TryFrom for AddressFamilyIdentifier { } } -impl Into> for AddressFamilyIdentifier { - fn into(self) -> Vec { - match self { - Self::Ipv4 => 1_u16.to_be_bytes().to_vec(), - Self::Ipv6 => 2_u16.to_be_bytes().to_vec(), +impl From for Vec { + fn from(val: AddressFamilyIdentifier) -> Self { + match val { + AddressFamilyIdentifier::Ipv4 => 1_u16.to_be_bytes().to_vec(), + AddressFamilyIdentifier::Ipv6 => 2_u16.to_be_bytes().to_vec(), } } } /// Convenience functions to convert AddressFamilyIdentifier into those used by netlink. -impl Into for AddressFamilyIdentifier { - fn into(self) -> netlink_packet_route::AddressFamily { - match self { +impl From for netlink_packet_route::AddressFamily { + fn from(val: AddressFamilyIdentifier) -> Self { + match val { AddressFamilyIdentifier::Ipv4 => netlink_packet_route::AddressFamily::Inet, AddressFamilyIdentifier::Ipv6 => netlink_packet_route::AddressFamily::Inet6, } } } -impl Into for AddressFamilyIdentifier { - fn into(self) -> rtnetlink::IpVersion { - match self { +impl From for rtnetlink::IpVersion { + fn from(val: AddressFamilyIdentifier) -> Self { + match val { AddressFamilyIdentifier::Ipv4 => rtnetlink::IpVersion::V4, AddressFamilyIdentifier::Ipv6 => rtnetlink::IpVersion::V6, } @@ -113,14 +113,14 @@ pub enum SubsequentAddressFamilyIdentifier { MulticastMplsVpn, } -impl Into for SubsequentAddressFamilyIdentifier { - fn into(self) -> u8 { - match self { - Self::Unicast => 1, - Self::Multicast => 2, - Self::NlriWithMpls => 4, - Self::MplsLabeledVPN => 128, - Self::MulticastMplsVpn => 129, +impl From for u8 { + fn from(val: SubsequentAddressFamilyIdentifier) -> Self { + match val { + SubsequentAddressFamilyIdentifier::Unicast => 1, + SubsequentAddressFamilyIdentifier::Multicast => 2, + SubsequentAddressFamilyIdentifier::NlriWithMpls => 4, + SubsequentAddressFamilyIdentifier::MplsLabeledVPN => 128, + SubsequentAddressFamilyIdentifier::MulticastMplsVpn => 129, } } } diff --git a/crates/bgp_packet/src/messages.rs b/crates/bgp_packet/src/messages.rs index 8bf0f87..183e785 100644 --- a/crates/bgp_packet/src/messages.rs +++ b/crates/bgp_packet/src/messages.rs @@ -45,9 +45,9 @@ impl BGPMessageType { } } -impl Into for BGPMessageType { - fn into(self) -> u8 { - self.0 +impl From for u8 { + fn from(val: BGPMessageType) -> Self { + val.0 } } impl From for BGPMessageType { @@ -264,7 +264,7 @@ impl Decoder for Codec { let len: u16 = byteorder::BigEndian::read_u16(&buf[16..18]); if buf.len() < len.into() { // Not enough data to read this frame. - return Ok(None); + Ok(None) } else if buf.len() == len as usize { // Exactly one message here, parse and clear buf. let parse_result = BGPMessage::from_wire(&self.ctx, buf.as_ref()); @@ -306,7 +306,7 @@ impl WritablePacket for BGPMessage { { let mut tmp: [u8; 2] = [0u8; 2]; NetworkEndian::write_u16(&mut tmp, self.wire_len(ctx)?); - buf.extend_from_slice(&mut tmp); + buf.extend_from_slice(&tmp); } // Type buf.push(self.msg_type.into()); @@ -428,9 +428,9 @@ impl WritablePacket for OpenMessage { for opt in &self.options { count += (*opt).to_wire(ctx)?.len(); } - Ok(count + count .try_into() - .map_err(|_| "overflow in wire_len in OpenMessage")?) + .map_err(|_| "overflow in wire_len in OpenMessage") } } @@ -485,12 +485,12 @@ impl ReadablePacket for UpdateMessage { impl WritablePacket for UpdateMessage { fn to_wire(&self, ctx: &ParserContext) -> Result, &'static str> { let mut buf: Vec = Vec::new(); - let mut tmp: &mut [u8] = &mut [0u8; 2]; + let tmp: &mut [u8] = &mut [0u8; 2]; let mut wd_len: u16 = 0; for wd in &self.withdrawn_nlri { wd_len += wd.wire_len(ctx)?; } - NetworkEndian::write_u16(&mut tmp, wd_len); + NetworkEndian::write_u16(tmp, wd_len); buf.append(&mut tmp.to_vec()); for wd in &self.withdrawn_nlri { buf.extend(wd.to_wire(ctx)?); @@ -499,7 +499,7 @@ impl WritablePacket for UpdateMessage { for pattr in &self.path_attributes { pattr_len += pattr.wire_len(ctx)?; } - NetworkEndian::write_u16(&mut tmp, pattr_len); + NetworkEndian::write_u16(tmp, pattr_len); buf.extend(tmp.to_vec()); for pattr in &self.path_attributes { buf.extend(pattr.to_wire(ctx)?); @@ -566,7 +566,9 @@ mod tests { 0x02, 0x02, 0x00, 0x02, 0x02, 0x46, 0x00, 0x02, 0x06, 0x41, 0x04, 0x00, 0x00, 0x00, 0x2a, ]; - let ctx = &ParserContext::new().four_octet_asn(true).nlri_mode(Ipv4); + let ctx = &ParserContext::default() + .four_octet_asn(true) + .nlri_mode(Ipv4); let (buf, result) = BGPMessage::from_wire(ctx, open_msg_bytes).unwrap(); assert_eq!(buf.len(), 0); @@ -585,7 +587,9 @@ mod tests { 0x18, 0x02, 0x06, 0x01, 0x04, 0x00, 0x02, 0x00, 0x01, 0x02, 0x02, 0x02, 0x00, 0x02, 0x02, 0x80, 0x00, 0x02, 0x06, 0x41, 0x04, 0x00, 0x00, 0x22, 0x36, ]; - let ctx = &ParserContext::new().four_octet_asn(true).nlri_mode(Ipv4); + let ctx = &ParserContext::default() + .four_octet_asn(true) + .nlri_mode(Ipv4); let (buf, result) = BGPMessage::from_wire(ctx, open_msg_bytes).unwrap(); assert_eq!(buf.len(), 0); @@ -609,14 +613,16 @@ mod tests { 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xdf, 0x1e, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x0a, 0x18, 0xcb, 0x01, 0x4e, ]; - let ctx = &ParserContext::new().four_octet_asn(true).nlri_mode(Ipv4); + let ctx = &ParserContext::default() + .four_octet_asn(true) + .nlri_mode(Ipv4); let (buf, result) = BGPMessage::from_wire(ctx, update_msg_bytes).unwrap(); assert_eq!(buf.len(), 0); let want_str = "UpdateMessage [ withdrawn: announced: 203.1.78.0/24 path attributes: OriginPathAttribute::INCOMPLETEAS Path: { Segment [ Type: AS_SEGMENT 39540 57118 29691 1299 4739 ]] }NextHop: 185.95.219.36Communities: [ 1299:35000, 29691:4000, 29691:4021, 39540:4000, 39540:4010, 57118:2000, 57118:2010, ] LargeCommunities: [ 57118:20:0, 57118:20:10, ] ]"; assert_eq!(format!("{}", result), want_str); - let reencoded = result.to_wire(&ctx).unwrap(); + let reencoded = result.to_wire(ctx).unwrap(); assert_eq!(&reencoded, update_msg_bytes); } @@ -664,7 +670,7 @@ mod tests { for b in &buf { print!("0x{:02x}, ", b); } - assert_eq!(buf.as_ref(), update_msg_bytes.as_ref()); + assert_eq!(buf.as_ref(), update_msg_bytes); } #[test] diff --git a/crates/bgp_packet/src/nlri.rs b/crates/bgp_packet/src/nlri.rs index f795bea..0c19465 100644 --- a/crates/bgp_packet/src/nlri.rs +++ b/crates/bgp_packet/src/nlri.rs @@ -72,11 +72,9 @@ impl ReadablePacket for NLRI { let (buf, prefix) = take(octet_len)(buf)?; match ctx.nlri_mode { - None => { - return Err(Failure(BGPParserError::CustomText( - "nlri_mode not set in the context for NLRI::from_wire".to_string(), - ))); - } + None => Err(Failure(BGPParserError::CustomText( + "nlri_mode not set in the context for NLRI::from_wire".to_string(), + ))), Some(afi) => Ok(( buf, NLRI { @@ -115,8 +113,7 @@ impl<'de> Deserialize<'de> for NLRI { where D: serde::Deserializer<'de>, { - Self::try_from(String::deserialize(deserializer)?.as_str()) - .map_err(|e| de::Error::custom(e)) + Self::try_from(String::deserialize(deserializer)?.as_str()).map_err(de::Error::custom) } } @@ -207,7 +204,7 @@ impl TryInto for NLRI { impl TryFrom<&str> for NLRI { type Error = eyre::ErrReport; fn try_from(value: &str) -> Result { - let parts: Vec<&str> = value.split("/").collect(); + let parts: Vec<&str> = value.split('/').collect(); if parts.len() != 2 { bail!("Expected ip_addr/prefixlen but got: {}", value); } @@ -217,11 +214,11 @@ impl TryFrom<&str> for NLRI { let mut octets: Vec; let afi: AddressFamilyIdentifier; - if parts[0].contains(":") { + if parts[0].contains(':') { afi = AddressFamilyIdentifier::Ipv6; let addr: Ipv6Addr = Ipv6Addr::from_str(parts[0]).map_err(|e| eyre!(e))?; octets = addr.octets().to_vec(); - } else if parts[0].contains(".") { + } else if parts[0].contains('.') { afi = AddressFamilyIdentifier::Ipv4; let addr: Ipv4Addr = Ipv4Addr::from_str(parts[0]).map_err(|e| eyre!(e))?; octets = addr.octets().to_vec(); @@ -237,7 +234,7 @@ impl TryFrom<&str> for NLRI { let num_bytes = (prefixlen / 8) + 1; let mask = u8::MAX << (8 - (prefixlen % 8)); octets.truncate(num_bytes.into()); - if octets.len() > 0 { + if !octets.is_empty() { let last_pos = octets.len() - 1; octets[last_pos] &= mask; } @@ -282,7 +279,7 @@ mod tests { use std::convert::TryFrom; use super::NLRI; - use crate::constants::AddressFamilyIdentifier::{self, Ipv4, Ipv6}; + use crate::constants::AddressFamilyIdentifier::{Ipv4, Ipv6}; use crate::traits::ParserContext; use crate::traits::ReadablePacket; use crate::traits::WritablePacket; @@ -290,7 +287,9 @@ mod tests { #[test] fn test_basic_nlri_v6() { let nlri_bytes: &[u8] = &[0x20, 0x20, 0x01, 0xdb, 0x8]; - let ctx = &ParserContext::new().four_octet_asn(true).nlri_mode(Ipv6); + let ctx = &ParserContext::default() + .four_octet_asn(true) + .nlri_mode(Ipv6); let nlri_res: (&[u8], NLRI) = NLRI::from_wire(ctx, nlri_bytes).unwrap(); assert_eq!(nlri_res.1.afi, Ipv6); assert_eq!(nlri_res.1.prefixlen, 32); @@ -305,7 +304,9 @@ mod tests { #[test] fn test_basic_nlri_v4() { let nlri_bytes: &[u8] = &[0x18, 192, 168, 1]; - let ctx = &ParserContext::new().four_octet_asn(true).nlri_mode(Ipv4); + let ctx = &ParserContext::default() + .four_octet_asn(true) + .nlri_mode(Ipv4); let nlri_res: (&[u8], NLRI) = NLRI::from_wire(ctx, nlri_bytes).unwrap(); assert_eq!(nlri_res.1.afi, Ipv4); assert_eq!(nlri_res.1.prefixlen, 24); diff --git a/crates/bgp_packet/src/path_attributes.rs b/crates/bgp_packet/src/path_attributes.rs index bdace09..2df7609 100644 --- a/crates/bgp_packet/src/path_attributes.rs +++ b/crates/bgp_packet/src/path_attributes.rs @@ -472,10 +472,10 @@ impl ReadablePacket for NextHopPathAttribute { impl WritablePacket for NextHopPathAttribute { fn to_wire(&self, _: &ParserContext) -> Result, &'static str> { - return Ok(self.0.octets().to_vec()); + Ok(self.0.octets().to_vec()) } fn wire_len(&self, _: &ParserContext) -> Result { - return Ok(4); + Ok(4) } } @@ -584,7 +584,7 @@ impl ReadablePacket for AggregatorPathAttribute { ctx: &ParserContext, buf: &'a [u8], ) -> IResult<&'a [u8], Self, BGPParserError<&'a [u8]>> { - if !ctx.four_octet_asn.is_some() { + if ctx.four_octet_asn.is_none() { return Err(Failure(BGPParserError::CustomText( "Non four byte ASN not supported (AggregatorPathAttribute from_wire)".to_string(), ))); @@ -604,7 +604,8 @@ impl ReadablePacket for AggregatorPathAttribute { impl WritablePacket for AggregatorPathAttribute { fn to_wire(&self, ctx: &ParserContext) -> Result, &'static str> { - if !ctx.four_octet_asn.is_some() { + if ctx.four_octet_asn.is_none() { + // TODO: This should be gracefully handled, not panic! panic!("Non four byte ASN not supported (AggregatorPathAttribute from_wire)"); } let mut buf: Vec = vec![0u8; 4]; @@ -613,7 +614,8 @@ impl WritablePacket for AggregatorPathAttribute { Ok(buf) } fn wire_len(&self, ctx: &ParserContext) -> Result { - if !ctx.four_octet_asn.is_some() { + if ctx.four_octet_asn.is_none() { + // TODO: This should be gracefully handled, not panic! panic!("Non four byte ASN not supported (AggregatorPathAttribute from_wire)"); } Ok(8) @@ -733,7 +735,7 @@ impl WritablePacket for ExtendedCommunitiesPathAttribute { if !self.value.len() == 7 { return Err("ExtendedCommunitiesPathAttribute value length != 7"); } - Ok(vec![vec![self.t_high], self.value.to_owned()].concat()) + Ok([vec![self.t_high], self.value.to_owned()].concat()) } fn wire_len(&self, _: &ParserContext) -> Result { Ok(8) @@ -847,7 +849,7 @@ impl MPReachNLRIPathAttribute { // https://datatracker.ietf.org/doc/html/rfc2545 describes what the nexthop // field can contain. Returns a tuple of (global_nh, linklocal_nh) pub fn nexthop_to_v6(self) -> Option<(Ipv6Addr, Option)> { - return match self.nexthop.len() { + match self.nexthop.len() { 16 => { let nh_bytes: [u8; 16] = self.nexthop.try_into().unwrap(); Some((Ipv6Addr::from(nh_bytes), None)) @@ -861,7 +863,7 @@ impl MPReachNLRIPathAttribute { )) } _ => None, - }; + } } } @@ -1010,7 +1012,9 @@ mod tests { 0x02, 0x04, 0x00, 0x00, 0x9a, 0x74, 0x00, 0x00, 0xdf, 0x1e, 0x00, 0x00, 0x20, 0x1a, 0x00, 0x00, 0x78, 0xfc, ]; - let ctx = &ParserContext::new().four_octet_asn(true).nlri_mode(Ipv6); + let ctx = &ParserContext::default() + .four_octet_asn(true) + .nlri_mode(Ipv6); let result = &ASPathAttribute::from_wire(ctx, as_path_bytes).unwrap(); let expected_aspath: Vec = vec![39540, 57118, 8218, 30972]; @@ -1029,7 +1033,9 @@ mod tests { 0x02, 0x04, 0x00, 0x00, 0x9a, 0x74, 0x00, 0x00, 0xdf, 0x1e, 0x00, 0x00, 0x20, 0x1a, 0x00, 0x00, 0x78, 0xfc, 0x01, 0x02, 0x00, 0x00, 0x9a, 0x74, 0x00, 0x00, 0xdf, 0x1e, ]; - let ctx = &ParserContext::new().four_octet_asn(true).nlri_mode(Ipv6); + let ctx = &ParserContext::default() + .four_octet_asn(true) + .nlri_mode(Ipv6); let result = &ASPathAttribute::from_wire(ctx, as_path_bytes).unwrap(); let expected_aspath: Vec = vec![39540, 57118, 8218, 30972]; @@ -1048,7 +1054,9 @@ mod tests { #[test] fn test_next_hop_path_attribute() { let nh_bytes: &[u8] = &[192, 168, 1, 1]; - let ctx = &ParserContext::new().four_octet_asn(true).nlri_mode(Ipv6); + let ctx = &ParserContext::default() + .four_octet_asn(true) + .nlri_mode(Ipv6); let result = NextHopPathAttribute::from_wire(ctx, nh_bytes).unwrap(); assert_eq!(result.1 .0, "192.168.1.1".parse::().unwrap()); @@ -1060,7 +1068,9 @@ mod tests { #[test] fn test_multi_exit_discriminator_path_attribute() { let med_bytes: &[u8] = &[0xca, 0x00, 0x00, 0xbe]; - let ctx = &ParserContext::new().four_octet_asn(true).nlri_mode(Ipv6); + let ctx = &ParserContext::default() + .four_octet_asn(true) + .nlri_mode(Ipv6); let result = MultiExitDiscPathAttribute::from_wire(ctx, med_bytes).unwrap(); assert_eq!(result.1 .0, 3388997822); @@ -1072,7 +1082,9 @@ mod tests { #[test] fn test_local_pref_path_attribute() { let local_pref_bytes: &[u8] = &[0xca, 0x00, 0x00, 0xbe]; - let ctx = &ParserContext::new().four_octet_asn(true).nlri_mode(Ipv6); + let ctx = &ParserContext::default() + .four_octet_asn(true) + .nlri_mode(Ipv6); let result = LocalPrefPathAttribute::from_wire(ctx, local_pref_bytes).unwrap(); assert_eq!(result.1 .0, 3388997822); @@ -1090,7 +1102,9 @@ mod tests { 0xff, 0xf1, 0x73, 0xfb, 0x0f, 0xa0, 0x73, 0xfb, 0x0f, 0xc8, 0x9a, 0x74, 0x0f, 0xa0, 0x9a, 0x74, 0x0f, 0xb4, 0xdf, 0x1e, 0x07, 0xd0, 0xdf, 0x1e, 0x07, 0xe4, ]; - let ctx = &ParserContext::new().four_octet_asn(true).nlri_mode(Ipv6); + let ctx = &ParserContext::default() + .four_octet_asn(true) + .nlri_mode(Ipv6); let result = CommunitiesPathAttribute::from_wire(ctx, communities_bytes).unwrap(); let expected_communities: Vec<(u16, u16)> = vec![ (0, 0x32bd), @@ -1127,7 +1141,9 @@ mod tests { 0x00, 0x00, 0xdf, 0x1e, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xdf, 0x1e, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x14, ]; - let ctx = &ParserContext::new().four_octet_asn(true).nlri_mode(Ipv6); + let ctx = &ParserContext::default() + .four_octet_asn(true) + .nlri_mode(Ipv6); let result = LargeCommunitiesPathAttribute::from_wire(ctx, large_community_bytes).unwrap(); assert_eq!(result.1.values.len(), 2); assert_eq!(result.1.values[0].global_admin, 57118); @@ -1154,7 +1170,9 @@ mod tests { 0x20, 0x20, 0x01, 0x0d, 0xb8, // NLRI 1 0x10, 0xfe, 0x80, // NLRI 2 ]; - let ctx = &ParserContext::new().four_octet_asn(true).nlri_mode(Ipv6); + let ctx = &ParserContext::default() + .four_octet_asn(true) + .nlri_mode(Ipv6); let result: (&[u8], MPReachNLRIPathAttribute) = MPReachNLRIPathAttribute::from_wire(ctx, mp_reach_bytes).unwrap(); assert_eq!(result.1.afi, Ipv6); @@ -1184,7 +1202,9 @@ mod tests { 0x20, 0x20, 0x01, 0x0d, 0xb8, // NLRI 1 0x10, 0xfe, 0x80, // NLRI 2 ]; - let ctx = &ParserContext::new().four_octet_asn(true).nlri_mode(Ipv6); + let ctx = &ParserContext::default() + .four_octet_asn(true) + .nlri_mode(Ipv6); let result: (&[u8], MPUnreachNLRIPathAttribute) = MPUnreachNLRIPathAttribute::from_wire(ctx, mp_unreach_bytes).unwrap(); assert_eq!(result.1.afi, Ipv6); @@ -1201,7 +1221,7 @@ mod tests { // Tests the high level dispatching of the path attribute parser #[test] - fn test_path_attribute_parsing<'a>() { + fn test_path_attribute_parsing() { let path_attr_bytes: &[u8] = &[ 0x40, 0x01, 0x01, 0x00, 0x50, 0x02, 0x00, 0x1a, 0x02, 0x06, 0x00, 0x00, 0x9a, 0x74, 0x00, 0x00, 0x62, 0x03, 0x00, 0x00, 0x0b, 0x62, 0x00, 0x00, 0x19, 0x35, 0x00, 0x00, @@ -1212,10 +1232,14 @@ mod tests { 0x9a, 0x74, 0x0f, 0xbe, ]; - let ctx = &ParserContext::new().four_octet_asn(true).nlri_mode(Ipv6); + let ctx = &ParserContext::default() + .four_octet_asn(true) + .nlri_mode(Ipv6); let (buf, res): (_, Vec) = - nom::multi::many0(|buf: &'a [u8]| PathAttribute::from_wire(ctx, buf))(path_attr_bytes) - .unwrap(); + nom::multi::many0(|buf: &'static [u8]| PathAttribute::from_wire(ctx, buf))( + path_attr_bytes, + ) + .unwrap(); assert_eq!(buf.len(), 0); let expected_str = "[OriginPathAttribute(IGP), \ ASPathAttribute(ASPathAttribute { segments: \ diff --git a/crates/bgp_packet/src/traits.rs b/crates/bgp_packet/src/traits.rs index 7a5dec2..203fe1d 100644 --- a/crates/bgp_packet/src/traits.rs +++ b/crates/bgp_packet/src/traits.rs @@ -21,7 +21,7 @@ use nom::IResult; // ParserContext contains information pertinent to configurations which affect // how message parsing is to be handled. -#[derive(Debug, PartialEq, Clone)] +#[derive(Debug, Default, PartialEq, Clone)] pub struct ParserContext { // Whether the peer is RFC6793 compliant. pub four_octet_asn: Option, @@ -30,13 +30,6 @@ pub struct ParserContext { } impl ParserContext { - pub fn new() -> ParserContext { - ParserContext { - four_octet_asn: None, - nlri_mode: None, - } - } - pub fn four_octet_asn(mut self, v: bool) -> Self { self.four_octet_asn = Some(v); self diff --git a/crates/route_client/proto/route_service.proto b/crates/route_client/proto/route_service.proto index 40c3d84..11ea6f8 100644 --- a/crates/route_client/proto/route_service.proto +++ b/crates/route_client/proto/route_service.proto @@ -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 {} diff --git a/crates/route_client/src/connector.rs b/crates/route_client/src/connector.rs new file mode 100644 index 0000000..2b1ed70 --- /dev/null +++ b/crates/route_client/src/connector.rs @@ -0,0 +1,66 @@ +use std::str::FromStr; +use std::time::Duration; + +use bgp_packet::nlri::NLRI; +use eyre::Result; +use tonic::transport::{Channel, Endpoint, Uri}; + +use crate::proto::bgp_server_admin_service_client::BgpServerAdminServiceClient; +use crate::proto::{AnnouncementRequest, Prefix}; + +pub struct Connector { + client: BgpServerAdminServiceClient, +} + +impl Connector { + pub async fn new(addr: String) -> Result { + let uri = Uri::from_str(addr.as_str()).unwrap(); + let endpoint = Endpoint::from(uri).keep_alive_timeout(Duration::from_secs(10)); + let client = BgpServerAdminServiceClient::connect(endpoint).await?; + Ok(Self { client }) + } + + pub async fn send_announce(&mut self, peer_name: String, prefix: NLRI) -> Result<()> { + let request = AnnouncementRequest { + peer_name, + prefix: Some(Prefix { + ip_prefix: prefix.prefix, + prefix_len: prefix.prefixlen as i32, + address_family: match prefix.afi { + bgp_packet::constants::AddressFamilyIdentifier::Ipv4 => { + crate::proto::AddressFamily::IPv4.into() + } + bgp_packet::constants::AddressFamilyIdentifier::Ipv6 => { + crate::proto::AddressFamily::IPv6.into() + } + }, + }), + large_communities: vec![], + add: true, + }; + self.client.announce_to_peer(request).await?; + Ok(()) + } + + pub async fn send_withdraw(&mut self, peer_name: String, prefix: NLRI) -> Result<()> { + let request = AnnouncementRequest { + peer_name, + prefix: Some(Prefix { + ip_prefix: prefix.prefix, + prefix_len: prefix.prefixlen as i32, + address_family: match prefix.afi { + bgp_packet::constants::AddressFamilyIdentifier::Ipv4 => { + crate::proto::AddressFamily::IPv4.into() + } + bgp_packet::constants::AddressFamilyIdentifier::Ipv6 => { + crate::proto::AddressFamily::IPv6.into() + } + }, + }), + large_communities: vec![], + add: false, + }; + self.client.announce_to_peer(request).await?; + Ok(()) + } +} diff --git a/crates/route_client/src/lib.rs b/crates/route_client/src/lib.rs index a8edf50..44760af 100644 --- a/crates/route_client/src/lib.rs +++ b/crates/route_client/src/lib.rs @@ -12,6 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. +pub mod connector; pub mod fib_state; pub mod netlink; pub mod southbound_interface; diff --git a/crates/route_client/src/southbound_interface.rs b/crates/route_client/src/southbound_interface.rs index 93373ba..a97f9be 100644 --- a/crates/route_client/src/southbound_interface.rs +++ b/crates/route_client/src/southbound_interface.rs @@ -43,24 +43,16 @@ pub trait SouthboundInterface { /// DummyVerifier is a SouthboundInterface that checks that routes are not added more than /// once and not removed when there are none. -#[derive(Clone)] +#[derive(Clone, Default)] pub struct DummyVerifier { route_state: HashMap, } -impl std::default::Default for DummyVerifier { - fn default() -> DummyVerifier { - DummyVerifier { - route_state: HashMap::default(), - } - } -} - #[async_trait] impl SouthboundInterface for DummyVerifier { async fn get_all_routes( &mut self, - address_family: AddressFamilyIdentifier, + _address_family: AddressFamilyIdentifier, ) -> Result> { todo!(); } diff --git a/crates/server/proto/route_service.proto b/crates/server/proto/route_service.proto index 40c3d84..11ea6f8 100644 --- a/crates/server/proto/route_service.proto +++ b/crates/server/proto/route_service.proto @@ -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 {} diff --git a/crates/server/src/bgp_server.rs b/crates/server/src/bgp_server.rs index 585b06a..29d2f68 100644 --- a/crates/server/src/bgp_server.rs +++ b/crates/server/src/bgp_server.rs @@ -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; diff --git a/crates/server/src/peer.rs b/crates/server/src/peer.rs index 8705c1f..a26ef01 100644 --- a/crates/server/src/peer.rs +++ b/crates/server/src/peer.rs @@ -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( diff --git a/crates/server/src/route_server.rs b/crates/server/src/route_server.rs index fd9cac4..e8a57df 100644 --- a/crates/server/src/route_server.rs +++ b/crates/server/src/route_server.rs @@ -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( - mgr_ps: (u64, PathSet), - address_family: i32, - ) -> route_server::PathSet { - let mut proto_pathset = route_server::PathSet { + fn transform_pathset(mgr_ps: (u64, PathSet), 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>; + type StreamPathsStream = ReceiverStream>; async fn stream_paths( &self, diff --git a/tests/integration_tests/tests/basic_startup.rs b/tests/integration_tests/tests/basic_startup.rs index 40fbe6a..e39b4ae 100644 --- a/tests/integration_tests/tests/basic_startup.rs +++ b/tests/integration_tests/tests/basic_startup.rs @@ -29,8 +29,8 @@ use bgp_packet::messages::BGPSubmessage; use bgp_packet::traits::ParserContext; use bgp_server::bgp_server::Server; use bgp_server::config::{PeerConfig, PrefixAnnouncement, ServerConfig}; -use bgp_server::route_server::route_server::bgp_server_admin_service_client::BgpServerAdminServiceClient; -use bgp_server::route_server::route_server::PeerStatusRequest; +use bgp_server::route_server::proto::bgp_server_admin_service_client::BgpServerAdminServiceClient; +use bgp_server::route_server::proto::PeerStatusRequest; #[macro_use] extern crate serial_test; @@ -151,7 +151,7 @@ async fn test_bgp_listener_known_peer() { assert!(conn.write_all(open_msg_bytes).is_ok()); let mut open_buf = vec![0u8; 65536]; - conn.read(&mut open_buf).unwrap(); + let _ = conn.read(&mut open_buf).unwrap(); let mut codec = bgp_packet::messages::Codec { ctx: ParserContext { @@ -168,14 +168,14 @@ async fn test_bgp_listener_known_peer() { match response_open_msg.unwrap().payload { BGPSubmessage::OpenMessage(_open) => {} _ => { - assert!(false); + unreachable!(); } } // Check that the server sends a keepalive after the open message. let mut ka_buf = vec![0u8; 65536]; - conn.read(&mut ka_buf).unwrap(); + let _ = conn.read(&mut ka_buf).unwrap(); let response_ka_message = codec .decode(&mut bytes::BytesMut::from(ka_buf.as_slice())) .unwrap(); @@ -183,7 +183,7 @@ async fn test_bgp_listener_known_peer() { match response_ka_message.unwrap().payload { BGPSubmessage::KeepaliveMessage(_ka) => {} _ => { - assert!(false); + unreachable!(); } } @@ -240,7 +240,7 @@ async fn test_bgp_peer_statemachine_outbound_conn() { assert!(conn.write_all(open_msg_bytes).is_ok()); let mut open_buf = vec![0u8; 65536]; - conn.read(&mut open_buf).unwrap(); + let _ = conn.read(&mut open_buf).unwrap(); let mut codec = bgp_packet::messages::Codec { ctx: ParserContext { @@ -257,14 +257,14 @@ async fn test_bgp_peer_statemachine_outbound_conn() { match response_open_msg.unwrap().payload { BGPSubmessage::OpenMessage(_open) => {} _ => { - assert!(false); + unreachable!(); } } // Check that the server sends a keepalive after the open message. let mut ka_buf = vec![0u8; 65536]; - conn.read(&mut ka_buf).unwrap(); + let _ = conn.read(&mut ka_buf).unwrap(); let response_ka_message = codec .decode(&mut bytes::BytesMut::from(ka_buf.as_slice())) .unwrap(); @@ -272,7 +272,7 @@ async fn test_bgp_peer_statemachine_outbound_conn() { match response_ka_message.unwrap().payload { BGPSubmessage::KeepaliveMessage(_ka) => {} _ => { - assert!(false); + unreachable!(); } } @@ -330,7 +330,7 @@ async fn test_bgp_peer_statemachine_outbound_reconnection() { assert!(conn.write_all(open_msg_bytes).is_ok()); let mut open_buf = vec![0u8; 65536]; - conn.read(&mut open_buf).unwrap(); + let _ = conn.read(&mut open_buf).unwrap(); let mut codec = bgp_packet::messages::Codec { ctx: ParserContext { @@ -347,14 +347,14 @@ async fn test_bgp_peer_statemachine_outbound_reconnection() { match response_open_msg.unwrap().payload { BGPSubmessage::OpenMessage(_open) => {} _ => { - assert!(false); + unreachable!(); } } // Check that the server sends a keepalive after the open message. let mut ka_buf = vec![0u8; 65536]; - conn.read(&mut ka_buf).unwrap(); + let _ = conn.read(&mut ka_buf).unwrap(); let response_ka_message = codec .decode(&mut bytes::BytesMut::from(ka_buf.as_slice())) .unwrap(); @@ -362,7 +362,7 @@ async fn test_bgp_peer_statemachine_outbound_reconnection() { match response_ka_message.unwrap().payload { BGPSubmessage::KeepaliveMessage(_ka) => {} _ => { - assert!(false); + unreachable!(); } } @@ -383,7 +383,7 @@ async fn test_bgp_peer_statemachine_outbound_reconnection() { assert!(conn.write_all(open_msg_bytes).is_ok()); let mut open_buf = vec![0u8; 65536]; - conn.read(&mut open_buf).unwrap(); + let _ = conn.read(&mut open_buf).unwrap(); let mut codec = bgp_packet::messages::Codec { ctx: ParserContext { @@ -400,14 +400,14 @@ async fn test_bgp_peer_statemachine_outbound_reconnection() { match response_open_msg.unwrap().payload { BGPSubmessage::OpenMessage(_open) => {} _ => { - assert!(false); + unreachable!(); } } // Check that the server sends a keepalive after the open message. let mut ka_buf = vec![0u8; 65536]; - conn.read(&mut ka_buf).unwrap(); + let _ = conn.read(&mut ka_buf).unwrap(); let response_ka_message = codec .decode(&mut bytes::BytesMut::from(ka_buf.as_slice())) .unwrap(); @@ -415,7 +415,7 @@ async fn test_bgp_peer_statemachine_outbound_reconnection() { match response_ka_message.unwrap().payload { BGPSubmessage::KeepaliveMessage(_ka) => {} _ => { - assert!(false); + unreachable!(); } } @@ -487,7 +487,7 @@ async fn test_bgp_listener_known_peer_inbound_reconnection() { assert!(conn.write_all(open_msg_bytes).is_ok()); let mut open_buf = vec![0u8; 65536]; - conn.read(&mut open_buf).unwrap(); + let _ = conn.read(&mut open_buf).unwrap(); let mut codec = bgp_packet::messages::Codec { ctx: ParserContext { @@ -504,14 +504,14 @@ async fn test_bgp_listener_known_peer_inbound_reconnection() { match response_open_msg.unwrap().payload { BGPSubmessage::OpenMessage(_open) => {} _ => { - assert!(false); + unreachable!(); } } // Check that the server sends a keepalive after the open message. let mut ka_buf = vec![0u8; 65536]; - conn.read(&mut ka_buf).unwrap(); + let _ = conn.read(&mut ka_buf).unwrap(); let response_ka_message = codec .decode(&mut bytes::BytesMut::from(ka_buf.as_slice())) .unwrap(); @@ -519,7 +519,7 @@ async fn test_bgp_listener_known_peer_inbound_reconnection() { match response_ka_message.unwrap().payload { BGPSubmessage::KeepaliveMessage(_ka) => {} _ => { - assert!(false); + unreachable!(); } } @@ -540,7 +540,7 @@ async fn test_bgp_listener_known_peer_inbound_reconnection() { let mut open_buf = vec![0u8; 65536]; conn.set_read_timeout(Some(Duration::from_secs(3))).unwrap(); - conn.read(&mut open_buf).unwrap(); + let _ = conn.read(&mut open_buf).unwrap(); let mut codec = bgp_packet::messages::Codec { ctx: ParserContext { @@ -557,7 +557,7 @@ async fn test_bgp_listener_known_peer_inbound_reconnection() { match response_open_msg.unwrap().payload { BGPSubmessage::OpenMessage(_open) => {} _ => { - assert!(false); + unreachable!(); } } @@ -607,7 +607,7 @@ async fn test_multi_instance_announce() { config_b.grpc_addr = Some("[::]:9182".to_owned()); config_b.peers[0].asn = 65535; config_b.peers[0].port = Some(9179); - config_b.peers[0].name = "config-a-peer".to_owned(); + config_b.peers[0].name = "config-a-peer".to_string(); let mut server_a = Server::new(config_a); server_a.start(true).await.unwrap();