Skip to content

Commit

Permalink
isis: implement the "lsp-too-large" YANG notification
Browse files Browse the repository at this point in the history
Signed-off-by: Renato Westphal <[email protected]>
  • Loading branch information
rwestphal committed Jan 3, 2025
1 parent fdc02dd commit 0d88e2f
Show file tree
Hide file tree
Showing 5 changed files with 36 additions and 13 deletions.
8 changes: 8 additions & 0 deletions holo-isis/src/debug.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ pub enum Debug<'a> {
PduTx(u32, MulticastAddr, &'a Pdu),
// Flooding
LspDiscard(LevelNumber, &'a Lsp),
LspTooLarge(&'a Interface, LevelNumber, &'a Lsp),
// LSDB maintenance
LspInstall(LevelNumber, &'a Lsp),
LspOriginate(LevelNumber, &'a Lsp),
Expand Down Expand Up @@ -164,6 +165,10 @@ impl Debug<'_> {
// Parent span(s): isis-instance
debug!(?level, lsp_id = %lsp.lsp_id.to_yang(), seqno = %lsp.seqno, len = %lsp.raw.len(), "{}", self);
}
Debug::LspTooLarge(iface, level, lsp) => {
// Parent span(s): isis-instance
debug!(interface = %iface.name, ?level, lsp_id = %lsp.lsp_id.to_yang(), len = %lsp.raw.len(), "{}", self);
}
Debug::LspPurge(level, lsp, reason) => {
// Parent span(s): isis-instance
debug!(?level, lsp_id = %lsp.lsp_id.to_yang(), seqno = %lsp.seqno, len = %lsp.raw.len(), ?reason, "{}", self);
Expand Down Expand Up @@ -237,6 +242,9 @@ impl std::fmt::Display for Debug<'_> {
Debug::LspDiscard(..) => {
write!(f, "discarding LSP")
}
Debug::LspTooLarge(..) => {
write!(f, "LSP larger than interface MTU")
}
Debug::LspInstall(..) => {
write!(f, "installing LSP")
}
Expand Down
14 changes: 7 additions & 7 deletions holo-isis/src/events.rs
Original file line number Diff line number Diff line change
Expand Up @@ -543,7 +543,7 @@ pub(crate) fn process_pdu_lsp(
// from the network.
lsp.set_rem_lifetime(0);
for iface in arenas.interfaces.iter_mut() {
iface.srm_list_add(level, lsp.clone());
iface.srm_list_add(instance, level, lsp.clone());
}
return Ok(());
}
Expand Down Expand Up @@ -591,7 +591,7 @@ pub(crate) fn process_pdu_lsp(
.iter_mut()
.filter(|other_iface| other_iface.id != iface_id)
{
other_iface.srm_list_add(level, lsp.clone());
other_iface.srm_list_add(instance, level, lsp.clone());
other_iface.ssn_list_del(level, &lsp.lsp_id);
}
}
Expand Down Expand Up @@ -632,7 +632,7 @@ pub(crate) fn process_pdu_lsp(
Some(Ordering::Greater) => {
// Update LSP flooding flags for the incoming interface.
let lsp_id = lsp.lsp_id;
iface.srm_list_add(level, lsp);
iface.srm_list_add(instance, level, lsp);
iface.ssn_list_del(level, &lsp_id);
}
}
Expand Down Expand Up @@ -753,7 +753,7 @@ pub(crate) fn process_pdu_snp(
}
Ordering::Greater => {
iface.ssn_list_del(level, &entry.lsp_id);
iface.srm_list_add(level, lse.data.clone());
iface.srm_list_add(instance, level, lse.data.clone());
}
Ordering::Less => {
iface.ssn_list_add(level, *entry);
Expand Down Expand Up @@ -789,7 +789,7 @@ pub(crate) fn process_pdu_snp(
for lsp in instance
.state
.lsdb
.get_mut(level)
.get(level)
.range(&arenas.lsp_entries, start..=end)
.map(|lse| &lse.data)
.filter(|lsp| !lsp_entries.contains_key(&lsp.lsp_id))
Expand All @@ -798,7 +798,7 @@ pub(crate) fn process_pdu_snp(
// Exclude LSPs with zero sequence number.
.filter(|lsp| lsp.seqno != 0)
{
iface.srm_list_add(level, lsp.clone());
iface.srm_list_add(instance, level, lsp.clone());
}
}

Expand Down Expand Up @@ -1106,7 +1106,7 @@ pub(crate) fn process_lsp_purge(

// Send purged LSP to all interfaces.
for iface in arenas.interfaces.iter_mut() {
iface.srm_list_add(level, lsp.clone());
iface.srm_list_add(instance, level, lsp.clone());
}

// Mark the LSP as purged and start the delete timer.
Expand Down
14 changes: 13 additions & 1 deletion holo-isis/src/interface.rs
Original file line number Diff line number Diff line change
Expand Up @@ -587,7 +587,12 @@ impl Interface {
self.state.tasks.csnp_interval = Default::default();
}

pub(crate) fn srm_list_add(&mut self, level: LevelNumber, mut lsp: Lsp) {
pub(crate) fn srm_list_add(
&mut self,
instance: &InstanceUpView<'_>,
level: LevelNumber,
mut lsp: Lsp,
) {
if !self.state.active {
return;
}
Expand All @@ -598,6 +603,13 @@ impl Interface {
return;
}

// Check if the LSP is too large to be sent on this interface.
if lsp.raw.len() as u32 > self.system.mtu.unwrap() {
Debug::LspTooLarge(self, level, &lsp).log();
notification::lsp_too_large(instance, self, &lsp);
return;
}

// ISO 10589 - Section 7.3.16.3:
// "A system shall decrement the Remaining Lifetime in the PDU being
// transmitted by at least one".
Expand Down
2 changes: 1 addition & 1 deletion holo-isis/src/lsdb.rs
Original file line number Diff line number Diff line change
Expand Up @@ -594,7 +594,7 @@ pub(crate) fn lsp_originate(

// Flood LSP over all interfaces.
for iface in arenas.interfaces.iter_mut() {
iface.srm_list_add(level, lse.data.clone());
iface.srm_list_add(instance, level, lse.data.clone());
}

// Schedule LSP refreshing.
Expand Down
11 changes: 7 additions & 4 deletions holo-isis/src/northbound/notification.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,11 @@ pub(crate) fn database_overload(instance: &InstanceUpView<'_>, overload: bool) {
notification::send(&instance.tx.nb, path, data);
}

#[expect(unused)]
pub(crate) fn lsp_too_large(instance: &InstanceUpView<'_>, iface: &Interface) {
pub(crate) fn lsp_too_large(
instance: &InstanceUpView<'_>,
iface: &Interface,
lsp: &Lsp,
) {
use yang::lsp_too_large::{self, LspTooLarge};

let path = lsp_too_large::PATH;
Expand All @@ -47,8 +50,8 @@ pub(crate) fn lsp_too_large(instance: &InstanceUpView<'_>, iface: &Interface) {
interface_name: Some(Cow::Borrowed(&iface.name)),
interface_level: Some(iface.config.level_type.resolved.to_yang()),
extended_circuit_id: None,
pdu_size: None,
lsp_id: None,
pdu_size: Some(lsp.raw.len() as u32),
lsp_id: Some(lsp.lsp_id.to_yang()),
};
notification::send(&instance.tx.nb, path, data);
}
Expand Down

0 comments on commit 0d88e2f

Please sign in to comment.