Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

0xPop #199

Merged
merged 39 commits into from
May 4, 2024
Merged

0xPop #199

Show file tree
Hide file tree
Changes from 37 commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
c602b14
start interop lab
rcgoodfellow Apr 3, 2024
619023e
Allow operator to specify ASN of BGP Peer
rcgoodfellow Apr 7, 2024
16b2ede
add ttl security
rcgoodfellow Apr 7, 2024
8509fcc
bgp: add tcp-md5 auth option for sessions
rcgoodfellow Apr 8, 2024
ffa4716
bgp: hold/keepalive negotiation
rcgoodfellow Apr 8, 2024
80601bf
bgp: multi-exit discriminator support
rcgoodfellow Apr 9, 2024
1b53719
add operator configurable communities per-session
rcgoodfellow Apr 11, 2024
957e639
add support for operator defined local preferences
rcgoodfellow Apr 11, 2024
8b71359
reticulating best-path
rcgoodfellow Apr 12, 2024
0a4e5be
reticulating splines
rcgoodfellow Apr 12, 2024
f580876
reticulating splines
rcgoodfellow Apr 13, 2024
fbcf6eb
move bestpath selection to upper half
rcgoodfellow Apr 13, 2024
db6e906
add interoperability containerlab
rcgoodfellow Apr 13, 2024
15d696f
test cloud multi-AZ peering + various improvements
rcgoodfellow Apr 13, 2024
8b8d938
disable idle-hold-timer on idle state exit
rcgoodfellow Apr 14, 2024
5a8b903
add enforce-first-as option
rcgoodfellow Apr 14, 2024
d91c783
ipv4 unicast nlri checking
rcgoodfellow Apr 14, 2024
96dea2f
add martian detection
rcgoodfellow Apr 14, 2024
2e523ae
foundations for a programmable policy engine
rcgoodfellow Apr 15, 2024
ffa38ca
policy shaping working
rcgoodfellow Apr 18, 2024
e4ab762
compute withdraws on shaper update
rcgoodfellow Apr 19, 2024
5ccf5a1
reticulating route refresh ....
rcgoodfellow Apr 21, 2024
2c8157e
a more regular bgp api ...
rcgoodfellow Apr 21, 2024
188174e
fix various issues found in testing
rcgoodfellow Apr 24, 2024
a6e30fd
add policy to omicron API
rcgoodfellow Apr 26, 2024
393b0a3
fix origin diff logic
rcgoodfellow Apr 26, 2024
3048693
omicron integration
rcgoodfellow Apr 27, 2024
6dde78e
fix dpd route sync: handle 404s
rcgoodfellow Apr 27, 2024
621db47
pin opte to omicron version
rcgoodfellow Apr 27, 2024
8575612
vlan plumbing
rcgoodfellow Apr 28, 2024
61b64a9
Revert "vlan plumbing"
rcgoodfellow Apr 29, 2024
3353d3b
keep it class-e
rcgoodfellow Apr 29, 2024
04708ad
plumb illumos MIN_TTL, fix some fsm issues along the way
rcgoodfellow May 1, 2024
46ad6f0
declarative per-peer import/export policy
rcgoodfellow May 2, 2024
e08940b
vlan plumbing
rcgoodfellow Apr 28, 2024
b2b5d2d
bump dendrite, netadm-sys to main
rcgoodfellow May 2, 2024
b6619ea
a bit of cleanup
rcgoodfellow May 2, 2024
6b36e5b
review feedback
rcgoodfellow May 3, 2024
6c4ab1a
review feedback
rcgoodfellow May 3, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1,070 changes: 554 additions & 516 deletions Cargo.lock

Large diffs are not rendered by default.

14 changes: 10 additions & 4 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -57,11 +57,11 @@ serde_repr = "0.1"
anyhow = "1.0.82"
hyper = "0.14.28"
serde_json = "1.0.116"
libnet = { git = "https://github.com/oxidecomputer/netadm-sys", branch = "main" }
percent-encoding = "2.3.1"
libnet = { git = "https://github.com/oxidecomputer/netadm-sys", branch = "compile-macos" }
reqwest = { version = "0.11", features = ["json", "stream", "rustls-tls"] }
progenitor = { git = "https://github.com/oxidecomputer/progenitor", branch = "main" }
clap = { version = "4.5.4", features = ["derive", "unstable-styles"] }
clap = { version = "4.5.4", features = ["derive", "unstable-styles", "env"] }
tabwriter = { version = "1", features = ["ansi_formatting"] }
colored = "2.1"
ctrlc = { version = "3.4.4", features = ["termination"] }
Expand All @@ -86,14 +86,17 @@ omicron-common = { git = "https://github.com/oxidecomputer/omicron", branch= "ma
internal-dns = { git = "https://github.com/oxidecomputer/omicron", branch = "main"}
uuid = { version = "1.8", features = ["serde", "v4"] }
smf = { git = "https://github.com/illumos/smf-rs", branch = "main" }
libc = "0.2"
itertools = "0.12"
rhai = { version = "1", features = ["metadata", "sync"] }

[workspace.dependencies.opte-ioctl]
git = "https://github.com/oxidecomputer/opte"
branch = "master"
rev = "7ee353a470ea59529ee1b34729681da887aa88ce"

[workspace.dependencies.oxide-vpc]
git = "https://github.com/oxidecomputer/opte"
branch = "master"
rev = "7ee353a470ea59529ee1b34729681da887aa88ce"

[workspace.dependencies.dpd-client]
git = "https://github.com/oxidecomputer/dendrite"
Expand All @@ -104,3 +107,6 @@ package = "dpd-client"
git = "https://github.com/oxidecomputer/dendrite"
branch = "main"
package = "common"

[patch."https://github.com/oxidecomputer/netadm-sys"]
libnet = { git = "https://www.github.com/oxidecomputer/netadm-sys.git", branch = "main" }
20 changes: 2 additions & 18 deletions bfd/src/sm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -438,15 +438,7 @@ impl State for Down {
db: rdb::Db,
counters: Arc<SessionCounters>,
) -> Result<(Box<dyn State>, BfdEndpoint)> {
match self.peer {
IpAddr::V4(addr) => db.disable_nexthop4(addr),
IpAddr::V6(addr) => {
warn!(
self.log,
"{addr} is down but active mode ipv6 not implemented yet"
)
}
}
db.disable_nexthop(self.peer);
loop {
// Get an incoming message
let (_addr, msg) = match self.recv(
Expand Down Expand Up @@ -605,15 +597,7 @@ impl State for Up {
db: rdb::Db,
counters: Arc<SessionCounters>,
) -> Result<(Box<dyn State>, BfdEndpoint)> {
match self.peer {
IpAddr::V4(addr) => db.enable_nexthop4(addr),
IpAddr::V6(addr) => {
warn!(
self.log,
"{addr} is up but active mode ipv6 not implemented yet"
)
}
}
db.enable_nexthop(self.peer);
loop {
// Get an incoming message
let (_addr, msg) = match self.recv(
Expand Down
3 changes: 3 additions & 0 deletions bgp/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ sled.workspace = true
anyhow.workspace = true
mg-common.workspace = true
chrono.workspace = true
libc.workspace = true
socket2.workspace = true
rhai.workspace = true

[dev-dependencies]
pretty-hex.workspace = true
Expand Down
14 changes: 14 additions & 0 deletions bgp/policy/policy-check0.rhai
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
fn open(message, asn, addr) {
if !message.has_capability(CapabilityCode::FourOctetAs) {
return CheckerResult::Drop;
}
CheckerResult::Accept
}

fn update(message, asn, addr) {
// drop no-export community
if message.has_community(0xFFFFFF01) {
return CheckerResult::Drop;
}
CheckerResult::Accept
}
13 changes: 13 additions & 0 deletions bgp/policy/policy-shape0.rhai
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
fn open(message, asn, addr) {
if asn == 100 {
message.add_four_octet_as(74);
}
message.emit()
}

fn update(message, asn, addr) {
if asn == 100 {
message.add_community(1701);
}
message.emit()
}
11 changes: 11 additions & 0 deletions bgp/policy/shape-prefix0.rhai
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
fn open(message, asn, addr) {
message.emit()
}

fn update(message, asn, addr) {
if asn == 65402 {
// Apply a filter on both NLRI elements and withdraw elements
message.prefix_filter(|prefix| prefix.within("10.128.0.0/16"));
}
message.emit()
}
40 changes: 25 additions & 15 deletions bgp/src/clock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,20 +23,28 @@ pub struct Clock {

pub struct ClockTimers {
/// How long to wait between connection attempts.
pub connect_retry_timer: Timer,
pub connect_retry_timer: Mutex<Timer>,

/// Configured keepliave timer interval. May be distinct from actual
/// keepalive interval depending on session parameter negotiation.
pub keepalive_configured_interval: Mutex<Duration>,

/// Time between sending keepalive messages.
pub keepalive_timer: Timer,
pub keepalive_timer: Mutex<Timer>,

/// Configured hold timer interval. May be distinct from actual keepalive
/// interval depending on session parameter negotiation.
pub hold_configured_interval: Mutex<Duration>,

/// How long to keep a session alive between keepalive, update and/or
/// notification messages.
pub hold_timer: Timer,
pub hold_timer: Mutex<Timer>,

/// Amount of time that a peer is held in the idle state.
pub idle_hold_timer: Timer,
pub idle_hold_timer: Mutex<Timer>,

/// Interval to wait before sending out an open message.
pub delay_open_timer: Timer,
pub delay_open_timer: Mutex<Timer>,
}

impl Clock {
Expand All @@ -53,11 +61,13 @@ impl Clock {
) -> Self {
let shutdown = Arc::new(AtomicBool::new(false));
let timers = Arc::new(ClockTimers {
connect_retry_timer: Timer::new(connect_retry_interval),
keepalive_timer: Timer::new(keepalive_interval),
hold_timer: Timer::new(hold_interval),
idle_hold_timer: Timer::new(idle_hold_interval),
delay_open_timer: Timer::new(delay_open_interval),
connect_retry_timer: Mutex::new(Timer::new(connect_retry_interval)),
keepalive_configured_interval: Mutex::new(keepalive_interval),
keepalive_timer: Mutex::new(Timer::new(keepalive_interval)),
hold_configured_interval: Mutex::new(hold_interval),
hold_timer: Mutex::new(Timer::new(hold_interval)),
idle_hold_timer: Mutex::new(Timer::new(idle_hold_interval)),
delay_open_timer: Mutex::new(Timer::new(delay_open_interval)),
});
let join_handle = Arc::new(Self::run(
resolution,
Expand Down Expand Up @@ -98,35 +108,35 @@ impl Clock {
) {
Self::step(
resolution,
&timers.connect_retry_timer,
&timers.connect_retry_timer.lock().unwrap(),
FsmEvent::ConnectRetryTimerExpires,
s.clone(),
&log,
);
Self::step(
resolution,
&timers.keepalive_timer,
&timers.keepalive_timer.lock().unwrap(),
FsmEvent::KeepaliveTimerExpires,
s.clone(),
&log,
);
Self::step(
resolution,
&timers.hold_timer,
&timers.hold_timer.lock().unwrap(),
FsmEvent::HoldTimerExpires,
s.clone(),
&log,
);
Self::step(
resolution,
&timers.idle_hold_timer,
&timers.idle_hold_timer.lock().unwrap(),
FsmEvent::IdleHoldTimerExpires,
s.clone(),
&log,
);
Self::step(
resolution,
&timers.delay_open_timer,
&timers.delay_open_timer.lock().unwrap(),
FsmEvent::DelayOpenTimerExpires,
s.clone(),
&log,
Expand Down
19 changes: 19 additions & 0 deletions bgp/src/connection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,15 @@ use std::sync::mpsc::Sender;
use std::sync::{Arc, Mutex};
use std::time::Duration;

#[cfg(target_os = "linux")]
pub const MAX_MD5SIG_KEYLEN: usize = libc::TCP_MD5SIG_MAXKEYLEN;

#[cfg(target_os = "illumos")]
pub const MAX_MD5SIG_KEYLEN: usize = 80;

#[cfg(target_os = "macos")]
pub const MAX_MD5SIG_KEYLEN: usize = 80;

/// Implementors of this trait listen to and accept BGP connections.
pub trait BgpListener<Cnx: BgpConnection> {
/// Bind to an address and listen for connections.
Expand Down Expand Up @@ -48,6 +57,8 @@ pub trait BgpConnection: Send + Clone {
&self,
event_tx: Sender<FsmEvent<Self>>,
timeout: Duration,
min_ttl: Option<u8>,
md5_key: Option<String>,
) -> Result<(), Error>
where
Self: Sized;
Expand All @@ -61,4 +72,12 @@ pub trait BgpConnection: Send + Clone {

// Return the local address being used for the connection.
fn local(&self) -> Option<SocketAddr>;

fn set_min_ttl(&self, ttl: u8) -> Result<(), Error>;

fn set_md5_sig(
&self,
keylen: u16,
key: [u8; MAX_MD5SIG_KEYLEN],
) -> Result<(), Error>;
}
16 changes: 15 additions & 1 deletion bgp/src/connection_channel.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
/// code in this file is to implement BgpListener and BgpConnection such that
/// the core functionality of the BGP upper-half in `session.rs` may be tested
/// rapidly using a simulated network.
use crate::connection::{BgpConnection, BgpListener};
use crate::connection::{BgpConnection, BgpListener, MAX_MD5SIG_KEYLEN};
use crate::error::Error;
use crate::messages::Message;
use crate::session::FsmEvent;
Expand Down Expand Up @@ -159,6 +159,8 @@ impl BgpConnection for BgpConnectionChannel {
&self,
event_tx: Sender<FsmEvent<Self>>,
timeout: Duration,
_ttl_sec: Option<u8>,
_md5_key: Option<String>,
) -> Result<(), Error> {
debug!(self.log, "[{}] connecting", self.peer);
let (local, remote) = channel();
Expand Down Expand Up @@ -209,6 +211,18 @@ impl BgpConnection for BgpConnectionChannel {
fn local(&self) -> Option<SocketAddr> {
Some(self.addr)
}

fn set_min_ttl(&self, _ttl: u8) -> Result<(), Error> {
Ok(())
}

fn set_md5_sig(
&self,
_keylen: u16,
_key: [u8; MAX_MD5SIG_KEYLEN],
) -> Result<(), Error> {
Ok(())
}
}

impl BgpConnectionChannel {
Expand Down
Loading