-
Notifications
You must be signed in to change notification settings - Fork 17
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
isis: import initial IS-IS implementation
Signed-off-by: Renato Westphal <[email protected]>
- Loading branch information
Showing
48 changed files
with
16,081 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -142,7 +142,7 @@ specific needs. | |
|
||
## Compliance | ||
|
||
Holo supports the following IETF RFCs and Internet drafts: | ||
Holo supports the following Internet Standards: | ||
|
||
##### BFD | ||
|
||
|
@@ -174,6 +174,19 @@ Holo supports the following IETF RFCs and Internet drafts: | |
* RFC 8212 - Default External BGP (EBGP) Route Propagation Behavior without Policies | ||
* RFC 8642 - Policy Behavior for Well-Known BGP Communities | ||
|
||
##### IS-IS | ||
|
||
* ISO/IEC 10589 - Information technology — Telecommunications and information exchange between systems — Intermediate System to Intermediate System intra-domain routeing information exchange protocol for use in conjunction with the protocol for providing the connectionless-mode network service (ISO 8473) | ||
* RFC 1195 - Use of OSI IS-IS for Routing in TCP/IP and Dual Environments | ||
* RFC 3719 - Recommendations for Interoperable Networks using Intermediate System to Intermediate System (IS-IS) | ||
* RFC 3787 - Recommendations for Interoperable IP Networks using Intermediate System to Intermediate System (IS-IS) | ||
* RFC 5301 - Dynamic Hostname Exchange Mechanism for IS-IS | ||
* RFC 5304 - IS-IS Cryptographic Authentication | ||
* RFC 5305 - IS-IS Extensions for Traffic Engineering | ||
* RFC 5308 - Routing IPv6 with IS-IS | ||
* RFC 5310 - IS-IS Generic Cryptographic Authentication | ||
* RFC 8405 - Shortest Path First (SPF) Back-Off Delay Algorithm for Link-State IGPs | ||
|
||
##### MPLS LDP | ||
|
||
* RFC 5036 - LDP Specification | ||
|
@@ -224,6 +237,7 @@ Holo supports the following IETF RFCs and Internet drafts: | |
| ietf-ip@2018-01-09 | 52.17% | 0.00% | - | - | [40.00%](http://westphal.com.br/holo/ietf-ip.html) | | ||
| ietf-ipv4-unicast-routing@2018-03-13 | 100.00% | 100.00% | - | - | [100.00%](http://westphal.com.br/holo/ietf-ipv4-unicast-routing.html) | | ||
| ietf-ipv6-unicast-routing@2018-03-13 | 40.62% | 100.00% | - | - | [45.71%](http://westphal.com.br/holo/ietf-ipv6-unicast-routing.html) | | ||
| ietf-isis@2022-10-19 | 92.66% | 52.21% | 100.00% | 100.00% | [68.81%](http://westphal.com.br/holo/[email protected]) | | ||
| ietf-key-chain@2017-04-18 | 100.00% | 100.00% | - | - | [100.00%](http://westphal.com.br/holo/ietf-key-chain.html) | | ||
| ietf-mpls-ldp@2022-03-14 | 86.96% | 92.31% | 100.00% | 100.00% | [92.38%](http://westphal.com.br/holo/ietf-mpls-ldp.html) | | ||
| ietf-mpls@2020-12-18 | 0.00% | 57.14% | - | - | [35.29%](http://westphal.com.br/holo/ietf-mpls.html) | | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
[package] | ||
name = "holo-isis" | ||
version.workspace = true | ||
authors.workspace = true | ||
license.workspace = true | ||
edition.workspace = true | ||
|
||
[dependencies] | ||
async-trait.workspace = true | ||
bitflags.workspace = true | ||
bytes.workspace = true | ||
chrono.workspace = true | ||
derive-new.workspace = true | ||
enum-as-inner.workspace = true | ||
fletcher.workspace = true | ||
generational-arena.workspace = true | ||
ipnetwork.workspace = true | ||
itertools.workspace = true | ||
libc.workspace = true | ||
nix.workspace = true | ||
num-derive.workspace = true | ||
num-traits.workspace = true | ||
prefix-trie.workspace = true | ||
rand.workspace = true | ||
regex.workspace = true | ||
serde.workspace = true | ||
serde_json.workspace = true | ||
serde_with.workspace = true | ||
smallvec.workspace = true | ||
socket2.workspace = true | ||
tokio.workspace = true | ||
tracing.workspace = true | ||
yang3.workspace = true | ||
|
||
holo-northbound = { path = "../holo-northbound" } | ||
holo-protocol = { path = "../holo-protocol" } | ||
holo-utils = { path = "../holo-utils" } | ||
holo-yang = { path = "../holo-yang" } | ||
|
||
[dev-dependencies] | ||
criterion.workspace = true | ||
|
||
holo-isis = { path = ".", features = ["testing", "deterministic"] } | ||
holo-protocol = { path = "../holo-protocol", features = ["testing"] } | ||
holo-utils = { path = "../holo-utils", features = ["testing"] } | ||
|
||
[lints] | ||
#workspace = true | ||
|
||
[lints.clippy] | ||
len_without_is_empty = "allow" | ||
too_many_arguments = "allow" | ||
|
||
[features] | ||
default = [] | ||
testing = [] | ||
deterministic = [] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
Copyright (c) 2023 The Holo Core Contributors | ||
|
||
Permission is hereby granted, free of charge, to any person obtaining a copy | ||
of this software and associated documentation files (the "Software"), to deal | ||
in the Software without restriction, including without limitation the rights | ||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
copies of the Software, and to permit persons to whom the Software is | ||
furnished to do so, subject to the following conditions: | ||
|
||
The above copyright notice and this permission notice shall be included in all | ||
copies or substantial portions of the Software. | ||
|
||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
SOFTWARE. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,164 @@ | ||
// | ||
// Copyright (c) The Holo Core Contributors | ||
// | ||
// SPDX-License-Identifier: MIT | ||
// | ||
// Sponsored by NLnet as part of the Next Generation Internet initiative. | ||
// See: https://nlnet.nl/NGI0 | ||
// | ||
|
||
use std::collections::BTreeSet; | ||
use std::time::Instant; | ||
|
||
use chrono::Utc; | ||
use holo_utils::task::TimeoutTask; | ||
|
||
use crate::collections::AdjacencyId; | ||
use crate::debug::Debug; | ||
use crate::instance::InstanceUpView; | ||
use crate::interface::{Interface, InterfaceType}; | ||
use crate::northbound::notification; | ||
use crate::packet::{AreaAddr, LanId, LevelType, SystemId}; | ||
use crate::tasks; | ||
|
||
#[derive(Debug)] | ||
pub struct Adjacency { | ||
pub id: AdjacencyId, | ||
pub snpa: [u8; 6], | ||
pub system_id: SystemId, | ||
pub level_capability: LevelType, | ||
pub level_usage: LevelType, | ||
pub state: AdjacencyState, | ||
pub priority: Option<u8>, | ||
pub lan_id: Option<LanId>, | ||
pub area_addrs: BTreeSet<AreaAddr>, | ||
pub neighbors: BTreeSet<[u8; 6]>, | ||
pub last_uptime: Option<Instant>, | ||
pub holdtimer: Option<TimeoutTask>, | ||
} | ||
|
||
#[derive(Clone, Copy, Debug, Eq, PartialEq)] | ||
pub enum AdjacencyState { | ||
Down, | ||
Initializing, | ||
Up, | ||
} | ||
|
||
#[derive(Clone, Copy, Debug, Eq, PartialEq)] | ||
pub enum AdjacencyEvent { | ||
HelloOneWayRcvd, | ||
HelloTwoWayRcvd, | ||
HoldtimeExpired, | ||
LinkDown, | ||
Kill, | ||
} | ||
|
||
// ===== impl Adjacency ===== | ||
|
||
impl Adjacency { | ||
// Creates new adjacency. | ||
pub(crate) fn new( | ||
id: AdjacencyId, | ||
snpa: [u8; 6], | ||
system_id: SystemId, | ||
level_capability: LevelType, | ||
level_usage: LevelType, | ||
) -> Adjacency { | ||
let adj = Adjacency { | ||
id, | ||
snpa, | ||
system_id, | ||
level_capability, | ||
level_usage, | ||
state: AdjacencyState::Down, | ||
priority: None, | ||
lan_id: None, | ||
area_addrs: Default::default(), | ||
neighbors: Default::default(), | ||
last_uptime: None, | ||
holdtimer: None, | ||
}; | ||
Debug::AdjacencyCreate(&adj).log(); | ||
adj | ||
} | ||
|
||
// Transitions the adjacency state if different from the current one. | ||
pub(crate) fn state_change( | ||
&mut self, | ||
iface: &mut Interface, | ||
instance: &mut InstanceUpView<'_>, | ||
event: AdjacencyEvent, | ||
new_state: AdjacencyState, | ||
) { | ||
if self.state == new_state { | ||
return; | ||
} | ||
|
||
// Log the state transition. | ||
Debug::AdjacencyStateChange(self, new_state, event).log(); | ||
|
||
// Send YANG notification. | ||
notification::adjacency_state_change( | ||
instance, iface, self, new_state, event, | ||
); | ||
|
||
// Update counters. | ||
if new_state == AdjacencyState::Up { | ||
iface.state.event_counters.adjacency_number += 1; | ||
self.last_uptime = Some(Instant::now()); | ||
} else if self.state == AdjacencyState::Up { | ||
iface.state.event_counters.adjacency_number -= 1; | ||
} | ||
iface.state.event_counters.adjacency_changes += 1; | ||
iface.state.discontinuity_time = Utc::now(); | ||
|
||
// ISO 10589 does not require periodic CSNP transmission on | ||
// point-to-point interfaces. However, sending them helps prevent | ||
// synchronization issues, especially in mesh-group setups. | ||
if iface.config.interface_type == InterfaceType::PointToPoint { | ||
if new_state == AdjacencyState::Up { | ||
// Start CSNP interval task(s). | ||
iface.csnp_interval_start(instance); | ||
} else if self.state == AdjacencyState::Up { | ||
// Stop CSNP interval task(s). | ||
iface.csnp_interval_stop(); | ||
} | ||
} | ||
|
||
// If no adjacencies remain in the Up state, clear SRM and SSN lists. | ||
if iface.state.event_counters.adjacency_number == 0 { | ||
for level in iface.config.levels() { | ||
iface.state.srm_list.get_mut(level).clear(); | ||
iface.state.ssn_list.get_mut(level).clear(); | ||
} | ||
} | ||
|
||
// Effectively transition to the new state. | ||
self.state = new_state; | ||
|
||
// Schedule LSP reorigination. | ||
instance.schedule_lsp_origination(self.level_usage); | ||
} | ||
|
||
// Starts or resets the holdtime timer. | ||
pub(crate) fn holdtimer_reset( | ||
&mut self, | ||
iface: &Interface, | ||
instance: &InstanceUpView<'_>, | ||
holdtime: u16, | ||
) { | ||
if let Some(holdtimer) = self.holdtimer.as_mut() { | ||
holdtimer.reset(None); | ||
} else { | ||
let task = | ||
tasks::adjacency_holdtimer(self, iface, instance, holdtime); | ||
self.holdtimer = Some(task); | ||
} | ||
} | ||
} | ||
|
||
impl Drop for Adjacency { | ||
fn drop(&mut self) { | ||
Debug::AdjacencyDelete(self).log(); | ||
} | ||
} |
Oops, something went wrong.