Lots of refactoring and improvements. Script hooks.
Can now establish and hold a session with BIRD, successfully detect Down state, and call scripts on state change via an event dispatch engine. Can't maintain a session with VyOS. I think it is calculating the timers incorrectly, but don't trust my own implementation of course...
This commit is contained in:
5 files changed
+834
-352
No files matched your search
+75
@@ -0,0 +1,75 @@
|
||||
pub mod bfd;
|
||||
pub mod control;
|
||||
pub mod events;
|
||||
|
||||
use std::{
|
||||
fmt::{self, Display},
|
||||
net::IpAddr,
|
||||
time::Instant,
|
||||
};
|
||||
|
||||
use log::debug;
|
||||
use nix::sys::socket::{getsockopt, setsockopt, sockopt};
|
||||
use tokio::net::UdpSocket;
|
||||
|
||||
use crate::bfd::*;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct BfdSessionStats {
|
||||
pub local_ip: IpAddr,
|
||||
pub remote_ip: IpAddr,
|
||||
pub local_discr: BfdDiscriminator,
|
||||
pub remote_discr: BfdDiscriminator,
|
||||
pub state: BfdState,
|
||||
pub last_diag: BfdDiagnostic,
|
||||
pub control_packets_rx: u64,
|
||||
pub control_packets_tx: u64,
|
||||
pub last_change: Instant,
|
||||
pub detect_time: BfdInterval,
|
||||
pub base_interval: BfdInterval,
|
||||
}
|
||||
impl BfdSessionStats {
|
||||
pub fn with_base_interval(mut self, base_interval: BfdInterval) -> Self {
|
||||
self.base_interval = base_interval;
|
||||
self
|
||||
}
|
||||
}
|
||||
impl Display for BfdSessionStats {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
writeln!(
|
||||
f,
|
||||
"{:<20} {:<9} {:>6} {:>6}",
|
||||
self.remote_ip, self.state, self.control_packets_rx, self.control_packets_tx
|
||||
)?;
|
||||
write!(
|
||||
f,
|
||||
" LocalDiscr:{} RemoteDiscr:{} DetectTime: {} TxTime: {} Diag:{} Last: {}s",
|
||||
self.local_discr,
|
||||
self.remote_discr,
|
||||
self.detect_time,
|
||||
self.base_interval,
|
||||
self.last_diag,
|
||||
Instant::now().duration_since(self.last_change).as_secs()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_ttl_or_hop_limit(sock: &UdpSocket, hop_limit: u8) -> Result<(), std::io::Error> {
|
||||
let addr = sock.local_addr()?;
|
||||
if addr.is_ipv4() {
|
||||
debug!("IPv4 socket, setting ttl {}", hop_limit as u32);
|
||||
sock.set_ttl(hop_limit as u32)
|
||||
} else if addr.is_ipv6() {
|
||||
debug!("IPv6 socket, setting hop limit {}", hop_limit as i32);
|
||||
let i32_hop_limit = hop_limit as i32;
|
||||
if let Err(e) = setsockopt(sock, sockopt::Ipv6Ttl, &i32_hop_limit) {
|
||||
Err(std::io::Error::from_raw_os_error(e as i32))
|
||||
} else {
|
||||
let res = getsockopt(sock, sockopt::Ipv6Ttl)?;
|
||||
debug!("Got {} after setting {}", res, i32_hop_limit);
|
||||
Ok(())
|
||||
}
|
||||
} else {
|
||||
panic!("UdpSocket with no address family ?!")
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user