Skip to content

Commit

Permalink
ipv4 unicast nlri checking
Browse files Browse the repository at this point in the history
- addresses #210 for ipv4
  • Loading branch information
rcgoodfellow committed Apr 26, 2024
1 parent b0af04c commit 74c3d92
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 0 deletions.
10 changes: 10 additions & 0 deletions bgp/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
use std::{fmt::Display, net::IpAddr};

use num_enum::TryFromPrimitiveError;
use rdb::Prefix4;

#[derive(thiserror::Error, Debug)]
pub enum Error {
Expand Down Expand Up @@ -168,6 +169,15 @@ pub enum Error {

#[error("Hold time too small")]
HoldTimeTooSmall,

#[error("Invalid NLRI prefix")]
InvalidNlriPrefix(Prefix4),

#[error("Nexthop cannot equal prefix")]
NexthopSelf(IpAddr),

#[error("Nexthop missing")]
MissingNexthop,
}

#[derive(Debug)]
Expand Down
37 changes: 37 additions & 0 deletions bgp/src/session.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1634,6 +1634,8 @@ impl<Cnx: BgpConnection + 'static> SessionRunner<Cnx> {
/// Perform a set of checks on an update to see if we can accept it.
fn check_update(&self, update: &UpdateMessage) -> Result<(), Error> {
self.check_for_self_in_path(update)?;
self.check_v4_prefixes(update)?;
self.check_nexthop_self(update)?;
let info = lock!(self.session);
if info.enforce_first_as {
if let Some(peer_as) = info.remote_asn {
Expand Down Expand Up @@ -1675,6 +1677,41 @@ impl<Cnx: BgpConnection + 'static> SessionRunner<Cnx> {
Ok(())
}

//TODO similar check needed for v6 once we get full v6 support
fn check_v4_prefixes(&self, update: &UpdateMessage) -> Result<(), Error> {
for prefix in &update.nlri {
if prefix.length == 0 {
continue;
}
let first = prefix.value[0];
// check 127.0.0.0/8, 224.0.0.0/4, 240.0.0.0/4
if (first == 127) || (first & 0xf0 == 224) || (first & 0xf0 == 240)
{
return Err(Error::InvalidNlriPrefix(prefix.as_prefix4()));
}
}
Ok(())
}

fn check_nexthop_self(&self, update: &UpdateMessage) -> Result<(), Error> {
// nothing to check when no prefixes presnt, and nexthop not required
// for pure withdraw
if update.nlri.is_empty() {
return Ok(());
}
let nexthop = match update.nexthop4() {
Some(nh) => nh,
None => return Err(Error::MissingNexthop),
};
for prefix in &update.nlri {
let prefix = prefix.as_prefix4();
if prefix.length == 32 && prefix.value == nexthop {
return Err(Error::NexthopSelf(prefix.value.into()));
}
}
Ok(())
}

fn enforce_first_as(
&self,
update: &UpdateMessage,
Expand Down

0 comments on commit 74c3d92

Please sign in to comment.