Skip to content

Commit 77fcc18

Browse files
committed
connect LIE state machine events to TIE subsystem
This commit adds a new broadcast event channel specifically for RIFT level peering events. These events are distinct from the lower level events that happen within the RIFT peering state machines, as those should stay within the peering state machines and not leak out into other subsystems. RIFT level peering events are specifically for entry and exit of three way adjacencies. When a three-way adjacency is accomplished, a peer-up event is emitted that carries with it the peer information, including the LIE message from the associated peer, and the link-local IPv6 interface that the peer can be reached on. The TIE subsystem listens for thse RIFT level peering events and responds to them by entering into TIE exchanges with established peers. Or in the case of peer-down events, clearing out routing state that is associated with the peer that has been lost.
1 parent bc7ce27 commit 77fcc18

File tree

10 files changed

+448
-43
lines changed

10 files changed

+448
-43
lines changed

Cargo.lock

Lines changed: 44 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

illumos/src/main.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
use rift::Rift;
77
use rift::config::Config;
8+
use rift_protocol::Level;
89
use slog;
910
use slog_term;
1011
use slog_async;
@@ -29,6 +30,7 @@ struct Opts {
2930
#[clap(short, long, parse(from_occurrences))]
3031
verbose: i32,
3132
id: u64,
33+
level: Level,
3234
}
3335

3436

@@ -44,7 +46,10 @@ async fn main() -> Result<(), String> {
4446
let opts: Opts = Opts::parse();
4547

4648
let ilu = Arc::new(Mutex::new(crate::platform::Illumos{log: log.clone()}));
47-
let mut riftp = Rift::new(ilu, log.clone(), Config{id: opts.id});
49+
let mut riftp = Rift::new(ilu, log.clone(), Config{
50+
id: opts.id,
51+
level: opts.level,
52+
});
4853
match riftp.run().await {
4954
Ok(()) => warn!(log, "early exit?"),
5055
Err(e) => error!(log, "rift: {}", e),

platform/src/lib.rs

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
pub mod error;
44

55
use std::net;
6+
use std::hash::{Hash, Hasher};
67
use error::Error;
78
use icmpv6::RDPMessage;
89
use tokio::sync::mpsc::{Sender, Receiver};
@@ -19,18 +20,21 @@ pub struct TIEPacketTx {
1920
}
2021

2122
pub trait Platform {
23+
// Local platform state
2224
fn get_links(&self) -> Result<Vec<LinkStatus>, Error>;
2325
fn get_link_status(&self, link_name: impl AsRef<str>) -> Result<LinkStatus, Error>;
2426
fn get_interface_v6ll(&self, interface: impl AsRef<str>) -> Result<Option<IpIfAddr>, Error>;
2527

26-
28+
// IPv6 RDP
2729
fn solicit_rift_routers(&self, interface: Option<IpIfAddr>) -> Result<(), Error>;
2830
fn advertise_rift_router(&self, interface: Option<IpIfAddr>) -> Result<(), Error>;
2931
fn get_rdp_channel(&self, interface: Option<IpIfAddr>) -> Result<Receiver<RDPMessage>, Error>;
30-
fn get_link_channel(&self, local: Ipv6Addr, peer: Ipv6Addr, local_ifx: i32) -> Result<
31-
(Sender<LIEPacket>, Receiver<LIEPacket>),
32-
Error
33-
>;
32+
33+
// RIFT Link Element Exchange (LIE)
34+
fn get_link_channel(&self, local: Ipv6Addr, peer: Ipv6Addr, local_ifx: i32)
35+
-> Result<(Sender<LIEPacket>, Receiver<LIEPacket>), Error>;
36+
37+
// RIFT Topology Element Exchange (TIE)
3438
fn get_topology_channel(&self) -> Result<(Sender<TIEPacketTx>, Receiver<TIEPacket>), Error>;
3539
}
3640

@@ -40,6 +44,14 @@ pub struct IpIfAddr {
4044
pub if_index: i32,
4145
}
4246

47+
impl Eq for IpIfAddr {}
48+
impl Hash for IpIfAddr {
49+
fn hash<H: Hasher>(&self, state: &mut H) {
50+
self.if_index.hash(state);
51+
self.addr.hash(state);
52+
}
53+
}
54+
4355
#[derive(Debug, Copy, Clone, Deserialize, Serialize, JsonSchema, PartialEq)]
4456
pub enum LinkState {
4557
Unknown,

rift/src/config.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
// Copyright 2021 Oxide Computer Company
22
use serde::{Deserialize, Serialize};
33
use schemars::JsonSchema;
4+
use rift_protocol::Level;
45

56
#[derive(Debug, Clone, Copy, Deserialize, Serialize, JsonSchema)]
67
pub struct Config {
78
pub id: u64,
9+
pub level: Level,
810
}

rift/src/lib.rs

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,14 @@ use std::time::SystemTime;
1010
use crate::error::Error;
1111
use std::net::Ipv6Addr;
1212
use std::sync::Arc;
13-
use tokio::sync::Mutex;
13+
use tokio::sync::{Mutex, broadcast};
1414
use tokio::time::sleep;
1515
use std::time::{Duration};
1616
use std::collections::HashSet;
1717
use std::hash::{Hash, Hasher};
1818
use schemars::JsonSchema;
1919
use serde::{Deserialize, Serialize};
20-
use platform::Platform;
20+
use platform::{Platform, IpIfAddr};
2121
use slog::{trace, info};
2222
use link::LinkSM;
2323
use rift_protocol::lie::{LIEPacket, Neighbor};
@@ -59,6 +59,12 @@ impl Peer {
5959
}
6060
}
6161

62+
#[derive(Debug, Clone)]
63+
enum PeerEvent {
64+
Up((Peer, IpIfAddr)),
65+
Down((Peer, IpIfAddr)),
66+
}
67+
6268
pub struct Rift<P: Platform + std::marker::Send + 'static> {
6369
platform: Arc::<Mutex::<P>>,
6470
links: Arc::<Mutex::<HashSet::<LinkSM>>>,
@@ -93,6 +99,17 @@ impl<P: Platform + std::marker::Send + std::marker::Sync> Rift<P> {
9399
p.get_links()?
94100
};
95101

102+
let (peer_event_tx, peer_event_rx) = broadcast::channel(32);
103+
104+
// start topology thread
105+
topology::tie_entry(
106+
self.log.clone(),
107+
self.platform.clone(),
108+
self.links.clone(),
109+
self.config,
110+
peer_event_rx,
111+
).await;
112+
96113
// start link state machines
97114
for l in links.iter() {
98115
let mut sm = link::LinkSM::new(
@@ -101,19 +118,14 @@ impl<P: Platform + std::marker::Send + std::marker::Sync> Rift<P> {
101118
l.state,
102119
self.config,
103120
);
104-
sm.run(self.platform.clone()).await;
121+
sm.run(
122+
self.platform.clone(),
123+
peer_event_tx.clone(),
124+
).await;
105125
let mut lsms = self.links.lock().await;
106126
lsms.insert(sm);
107127
}
108128

109-
// start topology thread
110-
if false {
111-
topology::tie_entry(
112-
self.log.clone(),
113-
self.platform.clone(),
114-
).await;
115-
}
116-
117129
self.router_loop().await?;
118130

119131
Ok(())

0 commit comments

Comments
 (0)