From 1a4e3eb1426067e26643abe64d94853f2baecad3 Mon Sep 17 00:00:00 2001 From: Renato Westphal Date: Tue, 26 Nov 2024 23:21:14 -0300 Subject: [PATCH] refactor --- holo-interface/src/ibus.rs | 24 +- holo-interface/src/interface.rs | 18 +- holo-utils/src/ibus.rs | 15 +- holo-utils/src/southbound.rs | 8 +- holo-vrrp/src/consts.rs | 6 +- holo-vrrp/src/debug.rs | 47 +- holo-vrrp/src/error.rs | 177 ++- holo-vrrp/src/events.rs | 287 ++--- holo-vrrp/src/instance.rs | 310 +++--- holo-vrrp/src/interface.rs | 419 ++----- holo-vrrp/src/lib.rs | 1 + holo-vrrp/src/macvlan.rs | 110 ++ holo-vrrp/src/network.rs | 190 ++-- holo-vrrp/src/northbound/configuration.rs | 106 +- holo-vrrp/src/northbound/state.rs | 3 +- holo-vrrp/src/northbound/yang.rs | 44 +- holo-vrrp/src/packet.rs | 98 +- holo-vrrp/src/southbound/rx.rs | 129 +-- holo-vrrp/src/southbound/tx.rs | 42 +- holo-vrrp/src/tasks.rs | 140 +-- holo-vrrp/tests/packet/mod.rs | 9 +- out | 535 --------- run.sh | 4 - yng | 1200 --------------------- 24 files changed, 972 insertions(+), 2950 deletions(-) create mode 100644 holo-vrrp/src/macvlan.rs delete mode 100644 out delete mode 100755 run.sh delete mode 100644 yng diff --git a/holo-interface/src/ibus.rs b/holo-interface/src/ibus.rs index 7f9f5be1..207b6e5a 100644 --- a/holo-interface/src/ibus.rs +++ b/holo-interface/src/ibus.rs @@ -57,7 +57,7 @@ pub(crate) async fn process_msg(master: &mut Master, msg: IbusMsg) { master.interfaces.router_id(), ); } - IbusMsg::CreateMacVlan(msg) => { + IbusMsg::MacvlanAdd(msg) => { master .interfaces .create_macvlan_interface( @@ -68,32 +68,28 @@ pub(crate) async fn process_msg(master: &mut Master, msg: IbusMsg) { ) .await; } + IbusMsg::MacvlanDel(ifname) => { + let _ = master + .interfaces + .delete_iface(&master.netlink_handle, ifname) + .await; + } IbusMsg::InterfaceIpAddRequest(msg) => { let _ = master .interfaces - .add_iface_address( - &master.netlink_handle, - msg.ifindex, - msg.addr, - ) + .add_iface_address(&master.netlink_handle, msg.ifname, msg.addr) .await; } - IbusMsg::InterfaceIpDeleteRequest(msg) => { + IbusMsg::InterfaceIpDelRequest(msg) => { let _ = master .interfaces .delete_iface_address( &master.netlink_handle, - msg.ifindex, + msg.ifname, msg.addr, ) .await; } - IbusMsg::InterfaceDeleteRequest(ifindex) => { - let _ = master - .interfaces - .delete_iface(&master.netlink_handle, ifindex) - .await; - } // Ignore other events. _ => {} } diff --git a/holo-interface/src/interface.rs b/holo-interface/src/interface.rs index 4b1bc578..53f94ab8 100644 --- a/holo-interface/src/interface.rs +++ b/holo-interface/src/interface.rs @@ -431,9 +431,11 @@ impl Interfaces { pub(crate) async fn delete_iface( &self, netlink_handle: &rtnetlink::Handle, - ifindex: u32, + ifname: String, ) { - if self.get_by_ifindex(ifindex).is_some() { + if let Some(iface) = self.get_by_name(&ifname) + && let Some(ifindex) = iface.ifindex + { let _ = netlink::iface_delete(netlink_handle, ifindex).await; } } @@ -442,10 +444,12 @@ impl Interfaces { pub(crate) async fn add_iface_address( &self, netlink_handle: &rtnetlink::Handle, - ifindex: u32, + ifname: String, addr: IpNetwork, ) { - if self.get_by_ifindex(ifindex).is_some() { + if let Some(iface) = self.get_by_name(&ifname) + && let Some(ifindex) = iface.ifindex + { netlink::addr_install(netlink_handle, ifindex, &addr).await; } } @@ -453,10 +457,12 @@ impl Interfaces { pub(crate) async fn delete_iface_address( &self, netlink_handle: &rtnetlink::Handle, - ifindex: u32, + ifname: String, addr: IpNetwork, ) { - if self.get_by_ifindex(ifindex).is_some() { + if let Some(iface) = self.get_by_name(&ifname) + && let Some(ifindex) = iface.ifindex + { netlink::addr_uninstall(netlink_handle, ifindex, &addr).await; } } diff --git a/holo-utils/src/ibus.rs b/holo-utils/src/ibus.rs index f8e4c677..4ca50ca4 100644 --- a/holo-utils/src/ibus.rs +++ b/holo-utils/src/ibus.rs @@ -18,9 +18,8 @@ use crate::policy::{MatchSets, Policy}; use crate::protocol::Protocol; use crate::southbound::{ AddressMsg, BierNbrInstallMsg, BierNbrUninstallMsg, - InterfaceIpAddRequestMsg, InterfaceIpDeleteRequestMsg, InterfaceUpdateMsg, - LabelInstallMsg, LabelUninstallMsg, MacvlanCreateMsg, RouteKeyMsg, - RouteMsg, + InterfaceIpAddRequestMsg, InterfaceIpDelRequestMsg, InterfaceUpdateMsg, + LabelInstallMsg, LabelUninstallMsg, MacvlanAddMsg, RouteKeyMsg, RouteMsg, }; use crate::sr::SrCfg; @@ -66,18 +65,18 @@ pub enum IbusMsg { InterfaceAddressAdd(AddressMsg), // Interface address delete notification. InterfaceAddressDel(AddressMsg), - // Create a Macvlan Address - CreateMacVlan(MacvlanCreateMsg), // Request to add an address to an interface. InterfaceIpAddRequest(InterfaceIpAddRequestMsg), // Request to delete an address to an interface. - InterfaceIpDeleteRequest(InterfaceIpDeleteRequestMsg), - // Request to delete an interface - InterfaceDeleteRequest(u32), + InterfaceIpDelRequest(InterfaceIpDelRequestMsg), // Keychain update notification. KeychainUpd(Arc), // Keychain delete notification. KeychainDel(String), + // Create a macvlan interface. + MacvlanAdd(MacvlanAddMsg), + // Delete a macvlan interface. + MacvlanDel(String), // Nexthop tracking registration. NexthopTrack(IpAddr), // Nexthop tracking unregistration. diff --git a/holo-utils/src/southbound.rs b/holo-utils/src/southbound.rs index 31fe0a20..363c06d8 100644 --- a/holo-utils/src/southbound.rs +++ b/holo-utils/src/southbound.rs @@ -81,7 +81,7 @@ pub struct InterfaceUpdateMsg { #[derive(Clone, Debug)] #[derive(Deserialize, Serialize)] -pub struct MacvlanCreateMsg { +pub struct MacvlanAddMsg { pub parent_name: String, pub name: String, pub mac_address: Option<[u8; 6]>, @@ -90,14 +90,14 @@ pub struct MacvlanCreateMsg { #[derive(Clone, Debug)] #[derive(Deserialize, Serialize)] pub struct InterfaceIpAddRequestMsg { - pub ifindex: u32, + pub ifname: String, pub addr: IpNetwork, } #[derive(Clone, Debug)] #[derive(Deserialize, Serialize)] -pub struct InterfaceIpDeleteRequestMsg { - pub ifindex: u32, +pub struct InterfaceIpDelRequestMsg { + pub ifname: String, pub addr: IpNetwork, } diff --git a/holo-vrrp/src/consts.rs b/holo-vrrp/src/consts.rs index 94eba0c0..e1df4009 100644 --- a/holo-vrrp/src/consts.rs +++ b/holo-vrrp/src/consts.rs @@ -6,9 +6,11 @@ // Sponsored by NLnet as part of the Next Generation Internet initiative. // See: https://nlnet.nl/NGI0 // + use std::net::Ipv4Addr; // ==== VRRP === + // valid vrrp versions pub const VALID_VRRP_VERSIONS: [u8; 1] = [2]; pub const VRRP_PROTO_NUMBER: i32 = 112; @@ -26,7 +28,9 @@ pub const VRRP_MULTICAST_ADDRESS: Ipv4Addr = Ipv4Addr::new(224, 0, 0, 18); pub const VRRP_IP_COUNT_MAX: usize = 20; // ==== ARP ==== -pub const ARP_PROTOCOL_NUMBER: u16 = 0x806_u16; + +pub const ARP_PROTOCOL_NUMBER: u16 = 0x0806; // ==== IP ==== + pub const IP_HDR_MIN: usize = 20; diff --git a/holo-vrrp/src/debug.rs b/holo-vrrp/src/debug.rs index 62d1ed75..09025f1a 100644 --- a/holo-vrrp/src/debug.rs +++ b/holo-vrrp/src/debug.rs @@ -7,35 +7,42 @@ // See: https://nlnet.nl/NGI0 // -use std::net::IpAddr; +use std::net::Ipv4Addr; use tracing::{debug, debug_span}; +use crate::instance::fsm; use crate::packet::VrrpHdr; // VRRP debug messages. #[derive(Debug)] pub enum Debug<'a> { - InstanceCreate, - InstanceDelete, + // Instances + InstanceCreate(u8), + InstanceDelete(u8), + InstanceStateChange(u8, fsm::State, fsm::State), // Network - PacketRx(&'a IpAddr, &'a VrrpHdr), - PacketTx(&'a IpAddr, &'a VrrpHdr), + PacketRx(&'a Ipv4Addr, &'a VrrpHdr), + PacketTx(&'a VrrpHdr), + ArpTx(&'a Ipv4Addr), } // ===== impl Debug ===== impl Debug<'_> { // Log debug message using the tracing API. - #[expect(unused)] pub(crate) fn log(&self) { match self { - Debug::InstanceCreate | Debug::InstanceDelete => { - // Parent span(s): vrrp-instance - debug!("{}", self); + Debug::InstanceCreate(vrid) | Debug::InstanceDelete(vrid) => { + // Parent span(s): vrrp + debug!(%vrid, "{}", self); + } + Debug::InstanceStateChange(vrid, old_state, new_state) => { + // Parent span(s): vrrp + debug!(%vrid, ?old_state, ?new_state, "{}", self); } Debug::PacketRx(src, packet) => { - // Parent span(s): vrrp-instance + // Parent span(s): vrrp debug_span!("network").in_scope(|| { debug_span!("input").in_scope(|| { let data = serde_json::to_string(&packet).unwrap(); @@ -43,10 +50,14 @@ impl Debug<'_> { }) }) } - Debug::PacketTx(addr, packet) => { - // Parent span(s): vrrp-instance:network:output + Debug::PacketTx(packet) => { + // Parent span(s): vrrp:network:output let data = serde_json::to_string(&packet).unwrap(); - debug!(%addr, %data, "{}", self); + debug!(%data, "{}", self); + } + Debug::ArpTx(addr) => { + // Parent span(s): vrrp:network:output + debug!(%addr, "{}", self); } } } @@ -55,15 +66,21 @@ impl Debug<'_> { impl std::fmt::Display for Debug<'_> { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { - Debug::InstanceCreate => { + Debug::InstanceCreate(..) => { write!(f, "instance created") } - Debug::InstanceDelete => { + Debug::InstanceDelete(..) => { write!(f, "instance deleted") } + Debug::InstanceStateChange(..) => { + write!(f, "instance state change") + } Debug::PacketRx(..) | Debug::PacketTx(..) => { write!(f, "packet") } + Debug::ArpTx(..) => { + write!(f, "gratuitous ARP") + } } } } diff --git a/holo-vrrp/src/error.rs b/holo-vrrp/src/error.rs index d594a64c..6628eb37 100644 --- a/holo-vrrp/src/error.rs +++ b/holo-vrrp/src/error.rs @@ -8,22 +8,34 @@ // use std::fmt::Debug; -use std::net::IpAddr; +use std::net::{IpAddr, Ipv4Addr}; -use tracing::{warn, warn_span}; +use tracing::warn; + +use crate::packet::DecodeError; // VRRP errors. #[derive(Debug)] pub enum Error { // I/O errors IoError(IoError), - InterfaceError(String), + // Packet input + GlobalError(Ipv4Addr, GlobalError), + VirtualRouterError(Ipv4Addr, VirtualRouterError), +} - // vrrp-ietf-yang-2018-03-13 specific errors - GlobalError(GlobalError), - VirtualRouterError(VirtualRouterError), +// VRRP I/O errors. +#[derive(Debug)] +pub enum IoError { + SocketError(std::io::Error), + MulticastJoinError(IpAddr, std::io::Error), + MulticastLeaveError(IpAddr, std::io::Error), + RecvError(std::io::Error), + RecvMissingSourceAddr, + SendError(std::io::Error), } +// VRRP error that occurred for a packet before it reaches a VRRP router. #[derive(Debug)] pub enum GlobalError { ChecksumError, @@ -32,6 +44,7 @@ pub enum GlobalError { VridError, } +// VRRP error that occurred after a packet reaches a VRRP router. #[derive(Debug)] pub enum VirtualRouterError { AddressListError, @@ -39,17 +52,6 @@ pub enum VirtualRouterError { PacketLengthError, } -// VRRP I/O errors. -#[derive(Debug)] -pub enum IoError { - SocketError(std::io::Error), - MulticastJoinError(IpAddr, std::io::Error), - MulticastLeaveError(IpAddr, std::io::Error), - RecvError(std::io::Error), - RecvMissingSourceAddr, - SendError(std::io::Error), -} - // ===== impl Error ===== impl Error { @@ -58,38 +60,12 @@ impl Error { Error::IoError(error) => { error.log(); } - Error::InterfaceError(error) => { - warn_span!("vrrp_interface_error").in_scope(|| warn!(error)); - } - Error::GlobalError(error) => { - match error { - GlobalError::ChecksumError => { - warn_span!("global_error").in_scope(|| { warn!("invalid checksum received") }) - }, - GlobalError::IpTtlError => { - warn_span!("global_error").in_scope(|| { warn!("TTL for IP packet is not 255.") }) - }, - GlobalError::VersionError => { - warn_span!("global_error").in_scope(|| { warn!("invalid version received. only version 2 accepted.") }) - }, - GlobalError::VridError => { - warn_span!("global_error").in_scope(|| { warn!("vrid is not locally configured. ") }) - }, - } - }, - Error::VirtualRouterError(error) => { - match error { - VirtualRouterError::AddressListError => { - warn_span!("vr_error").in_scope(|| { warn!("addresses received not locally configured") }) - }, - VirtualRouterError::IntervalError => { - warn_span!("vr_error").in_scope(|| { warn!("interval does not match locally configured interval") }) - }, - VirtualRouterError::PacketLengthError => { - warn_span!("vr_error").in_scope(|| { warn!("packet length error") }); - }, - } - }, + Error::GlobalError(source, error) => { + warn!(?source, %error, "{}", self); + } + Error::VirtualRouterError(source, error) => { + warn!(?source, %error, "{}", self); + } } } } @@ -98,58 +74,20 @@ impl std::fmt::Display for Error { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { Error::IoError(error) => std::fmt::Display::fmt(error, f), - Error::InterfaceError(error) => write!(f, "{}", error), - Error::GlobalError(error) => std::fmt::Display::fmt(error, f), - Error::VirtualRouterError(error) => { + Error::GlobalError(_, error) => std::fmt::Display::fmt(error, f), + Error::VirtualRouterError(_, error) => { std::fmt::Display::fmt(error, f) } } } } -impl std::fmt::Display for GlobalError { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - match self { - GlobalError::ChecksumError => { - write!(f, "incorrect checksum received") - } - GlobalError::IpTtlError => { - write!(f, "invalid ttl received. IP ttl for vrrp should always be 255") - } - GlobalError::VersionError => { - write!( - f, - "invalid VRRP version received. only version 2 accepted" - ) - } - GlobalError::VridError => { - write!(f, "vrid received is not in the configured VRIDs") - } - } - } -} - -impl std::fmt::Display for VirtualRouterError { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - match self { - VirtualRouterError::AddressListError => { - write!(f, "VRRP address received not in configured addresses") - } - VirtualRouterError::IntervalError => { - write!(f, "VRRP interval received not match locally configured interval") - } - VirtualRouterError::PacketLengthError => { - write!(f, "the VRRP packet should be between 16 bytes and 80 bytes. received packet not in range.") - } - } - } -} - impl std::error::Error for Error { fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { match self { Error::IoError(error) => Some(error), - _ => None, + Error::GlobalError(_, error) => Some(error), + Error::VirtualRouterError(_, error) => Some(error), } } } @@ -160,6 +98,20 @@ impl From for Error { } } +impl From<(Ipv4Addr, DecodeError)> for Error { + fn from((src, error): (Ipv4Addr, DecodeError)) -> Error { + match error { + DecodeError::ChecksumError => { + Error::GlobalError(src, GlobalError::ChecksumError) + } + DecodeError::PacketLengthError { .. } => Error::VirtualRouterError( + src, + VirtualRouterError::PacketLengthError, + ), + } + } +} + // ===== impl IoError ===== impl IoError { @@ -223,6 +175,49 @@ impl std::error::Error for IoError { } } +// ===== impl GlobalError ===== + +impl std::fmt::Display for GlobalError { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + GlobalError::ChecksumError => { + write!(f, "incorrect checksum received") + } + GlobalError::IpTtlError => { + write!(f, "invalid IP TTL received") + } + GlobalError::VersionError => { + write!(f, "unsupported VRRP version received") + } + GlobalError::VridError => { + write!(f, "invalid VRID received") + } + } + } +} + +impl std::error::Error for GlobalError {} + +// ===== impl VirtualRouterError ===== + +impl std::fmt::Display for VirtualRouterError { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + VirtualRouterError::AddressListError => { + write!(f, "address list mismatch") + } + VirtualRouterError::IntervalError => { + write!(f, "advertisement interval mismatch") + } + VirtualRouterError::PacketLengthError => { + write!(f, "invalid packet length") + } + } + } +} + +impl std::error::Error for VirtualRouterError {} + // ===== global functions ===== fn with_source(error: E) -> String { diff --git a/holo-vrrp/src/events.rs b/holo-vrrp/src/events.rs index a00aa840..0e6bbcbe 100644 --- a/holo-vrrp/src/events.rs +++ b/holo-vrrp/src/events.rs @@ -10,222 +10,145 @@ use std::net::Ipv4Addr; use std::time::Duration; -use tracing::{debug, debug_span}; +use chrono::Utc; use crate::consts::VALID_VRRP_VERSIONS; -use crate::error::{Error, IoError}; -use crate::instance::{Event, MasterReason, State}; +use crate::debug::Debug; +use crate::error::{Error, GlobalError, VirtualRouterError}; +use crate::instance::{fsm, MasterReason, VrrpTimer}; use crate::interface::Interface; -use crate::packet::{DecodeResult, VrrpHdr}; +use crate::packet::{DecodeError, DecodeResult, VrrpHdr}; use crate::tasks; -// To collect actions to be executed later -enum VrrpAction { - Initialize(Ipv4Addr, VrrpHdr), - Backup(Ipv4Addr, VrrpHdr), - Master(Ipv4Addr, VrrpHdr), -} +// ===== VRRP network packet receipt ===== -// ===== Vrrp Network packet receipt ===== pub(crate) fn process_vrrp_packet( interface: &mut Interface, - src_ip: Ipv4Addr, + src: Ipv4Addr, packet: DecodeResult, ) -> Result<(), Error> { - // Handle packet decoding errors - let pkt = match packet { - Ok(pkt) => pkt, - Err(err) => { - interface.add_error_stats(err); - return Err(Error::IoError(IoError::RecvError( - std::io::Error::new( - std::io::ErrorKind::Other, - "decoding error VRRP packet", - ), - ))); + // Check if the packet was decoded successfully. + let packet = match packet { + Ok(packet) => packet, + Err(error) => { + match error { + DecodeError::ChecksumError => { + interface.statistics.checksum_errors += 1; + interface.statistics.discontinuity_time = Utc::now(); + } + DecodeError::PacketLengthError { vrid } => { + if let Some(instance) = interface.instances.get_mut(&vrid) { + instance.state.statistics.pkt_length_errors += 1; + instance.state.statistics.discontinuity_time = + Utc::now(); + } + } + } + return Err(Error::from((src, error))); } }; - if let Some(instance) = interface.instances.get_mut(&pkt.vrid) { - // handling interval errors - if pkt.adver_int != instance.config.advertise_interval { - instance.state.statistics.interval_errors += 1; - let err = format!( - "advertisement interval received not matching local config: {}", - pkt.adver_int - ); - debug_span!("recv-error").in_scope(|| { - debug_span!("interval").in_scope(|| { - debug!("{}", err.as_str()); - }); - }); - return Err(Error::IoError(IoError::RecvError( - std::io::Error::new(std::io::ErrorKind::Other, err.as_str()), - ))); - } - - // handle version errors - if !VALID_VRRP_VERSIONS.contains(&pkt.version) { - instance.state.statistics.version_errors += 1; - let err = format!("invalid version received: {}", pkt.version); - debug_span!("recv-error").in_scope(|| { - debug_span!("version").in_scope(|| { - debug!("{}", err.as_str()); - }); - }); - return Err(Error::IoError(IoError::RecvError( - std::io::Error::new(std::io::ErrorKind::Other, err.as_str()), - ))); - } - - if pkt.priority == 0 { - instance.state.statistics.priority_zero_pkts_rcvd += 1; - } - } + // Log received packet. + Debug::PacketRx(&src, &packet).log(); - // collect the actions that are required - let action = match get_vrrp_action(interface, src_ip, pkt) { - Ok(a) => a, - Err(e) => return Err(e), + // Lookup instance. + let Some((interface, instance)) = interface.get_instance(packet.vrid) + else { + interface.statistics.vrid_errors += 1; + interface.statistics.discontinuity_time = Utc::now(); + return Err(Error::GlobalError(src, GlobalError::VridError)); }; - // execute all collected actions - handle_vrrp_actions(interface, action); - Ok(()) -} + // Update last advertised source address. + instance.state.last_adv_src = Some(src); -// gets all the actions that are required to be done bacsed on the interface -// configs and incoming packet -fn get_vrrp_action( - interface: &mut Interface, - src_ip: Ipv4Addr, - packet: VrrpHdr, -) -> Result { - // Handle missing instance - let instance = match interface.instances.get_mut(&packet.vrid) { - Some(instance) => instance, - None => { - return Err(Error::InterfaceError(String::from( - "unable to fetch VRRP instance from interface", - ))) - } - }; + // Sanity checks. + if !VALID_VRRP_VERSIONS.contains(&packet.version) { + interface.statistics.version_errors += 1; + interface.statistics.discontinuity_time = Utc::now(); + let error = GlobalError::VersionError; + return Err(Error::GlobalError(src, error)); + } + if packet.adver_int != instance.config.advertise_interval { + instance.state.statistics.interval_errors += 1; + instance.state.statistics.discontinuity_time = Utc::now(); + let error = VirtualRouterError::IntervalError; + return Err(Error::VirtualRouterError(src, error)); + } - // Update statistics + // Update statistics. instance.state.statistics.adv_rcvd += 1; - - // Handle the current state - match instance.state.state { - State::Initialize => Ok(VrrpAction::Initialize(src_ip, packet)), - State::Backup => Ok(VrrpAction::Backup(src_ip, packet)), - State::Master => Ok(VrrpAction::Master(src_ip, packet)), + if packet.priority == 0 { + instance.state.statistics.priority_zero_pkts_rcvd += 1; } -} + instance.state.statistics.discontinuity_time = Utc::now(); -fn handle_vrrp_actions(interface: &mut Interface, action: VrrpAction) { - match action { - VrrpAction::Initialize(_src, pkt) => { - let vrid = pkt.vrid; - let priority = pkt.priority; - - if priority == 255 { - interface.send_vrrp_advert(vrid); - interface.change_state( - vrid, - State::Master, - MasterReason::Priority, - ); - if let Some(instance) = - interface.instances.get_mut(&vrid).take() - { - instance.send_gratuitous_arp(); - } - } else { - interface.change_state( - vrid, - State::Backup, - MasterReason::NotMaster, - ); - } + // RFC 3768: Section 6.4.2 ("If an ADVERTISEMENT is received") + match instance.state.state { + fsm::State::Initialize => { + unreachable!() } - VrrpAction::Backup(_src, pkt) => { - let vrid = pkt.vrid; - - if let Some(instance) = interface.instances.get_mut(&vrid) { - if pkt.priority == 0 { - let duration = - Duration::from_secs_f32(instance.state.skew_time); - tasks::set_master_down_timer( - instance, - duration, - interface - .tx - .protocol_input - .master_down_timer_tx - .clone(), - ); - } else { - // RFC 3768 Section 6.4.2 - // If Preempt Mode if False, or if the priority in the ADVERTISEMENT is - // greater than or equal to local priority then: - if !instance.config.preempt - || (pkt.priority > instance.config.priority) - { - instance.reset_timer(); - } - // drop the packet - } + fsm::State::Backup => { + if packet.priority == 0 { + let duration = + Duration::from_secs_f32(instance.config.skew_time()); + let task = tasks::master_down_timer( + instance, + duration, + &interface.tx.protocol_input.master_down_timer_tx, + ); + instance.state.timer = VrrpTimer::MasterDownTimer(task); + } else if !instance.config.preempt + || packet.priority >= instance.config.priority + { + instance.timer_reset(); } } - - VrrpAction::Master(src, pkt) => { - let vrid = pkt.vrid; - let mut send_ad = false; - if let Some(instance) = interface.instances.get_mut(&vrid).take() { - if pkt.priority == 0 { - send_ad = true; - instance.reset_timer(); - } - //If the Priority in the ADVERTISEMENT is greater than the - // local Priority, - // or - // If the Priority in the ADVERTISEMENT is equal to the local - // Priority and the primary IP Address of the sender is greater - // than the local primary IP Address - else if pkt.priority > instance.config.priority - || ((pkt.priority == instance.config.priority) - && src - > interface.system.addresses.first().unwrap().ip()) - { - interface.change_state( - vrid, - State::Backup, - MasterReason::NotMaster, - ); - } - } - - if send_ad { - interface.send_vrrp_advert(vrid); + fsm::State::Master => { + let primary_addr = interface.system.addresses.first().unwrap().ip(); + if packet.priority == 0 { + instance.send_vrrp_advertisement(primary_addr); + instance.timer_reset(); + } else if packet.priority > instance.config.priority + || (packet.priority == instance.config.priority + && src > primary_addr) + { + instance.change_state( + &interface, + fsm::State::Backup, + MasterReason::NotMaster, + ); } } } + + Ok(()) } -// ====== Handle Master Down Timer ===== -// RFC 3768 : Section 6.4.2 -// 'If the Master_Down_timer fires' +// ====== Master down timer ===== + pub(crate) fn handle_master_down_timer( interface: &mut Interface, vrid: u8, ) -> Result<(), Error> { - interface.send_vrrp_advert(vrid); - if let Some(instance) = interface.instances.get_mut(&vrid) { - instance.state.last_event = Event::MasterTimeout; - instance.send_gratuitous_arp(); - } + // Lookup instance. + let Some((interface, instance)) = interface.get_instance(vrid) else { + return Ok(()); + }; + let Some(src_ip) = interface.system.addresses.first().map(|addr| addr.ip()) + else { + return Ok(()); + }; - interface.change_state(vrid, State::Master, MasterReason::NoResponse); + // RFC 3768: Section 6.4.2 ("If the Master_Down_timer fires") + instance.state.last_event = fsm::Event::MasterTimeout; + instance.send_vrrp_advertisement(src_ip); + instance.send_gratuitous_arp(); + instance.change_state( + &interface, + fsm::State::Master, + MasterReason::NoResponse, + ); Ok(()) } diff --git a/holo-vrrp/src/instance.rs b/holo-vrrp/src/instance.rs index 3c294e7a..33f8c09f 100644 --- a/holo-vrrp/src/instance.rs +++ b/holo-vrrp/src/instance.rs @@ -13,87 +13,89 @@ use std::sync::Arc; use std::time::Duration; use chrono::{DateTime, Utc}; +use enum_as_inner::EnumAsInner; use holo_utils::task::{IntervalTask, TimeoutTask}; -use crate::consts::VRRP_PROTO_NUMBER; -use crate::interface::MacVlanInterface; +use crate::consts::{VRRP_MULTICAST_ADDRESS, VRRP_PROTO_NUMBER}; +use crate::debug::Debug; +use crate::interface::InterfaceView; +use crate::macvlan::{MacvlanInterface, MacvlanNet}; use crate::northbound::configuration::InstanceCfg; -use crate::packet::{ArpHdr, EthernetHdr, Ipv4Hdr, VrrpHdr}; +use crate::packet::{ArpHdr, EthernetHdr, Ipv4Hdr, VrrpHdr, VrrpPacket}; use crate::tasks::messages::output::NetTxPacketMsg; +use crate::{southbound, tasks}; #[derive(Debug)] pub struct Instance { - // vrid + // Virtual Router ID. pub vrid: u8, - // Instance configuration data. pub config: InstanceCfg, - // Instance state data. pub state: InstanceState, - - // timers - pub timer: VrrpTimer, - - // mvlan - pub mac_vlan: MacVlanInterface, + // Macvlan interface. + pub mvlan: MacvlanInterface, } -#[derive(Debug)] -pub enum VrrpTimer { - Null, - AdverTimer(IntervalTask), - MasterDownTimer(TimeoutTask), -} - -#[derive(Debug)] +#[derive(Debug, Default)] pub struct InstanceState { - pub state: State, - pub last_adv_src: Option, - pub up_time: Option>, - pub last_event: Event, + pub state: fsm::State, + pub last_event: fsm::Event, pub new_master_reason: MasterReason, - pub skew_time: f32, - pub master_down_interval: u32, - pub is_owner: bool, - - // TODO: interval/timer tasks + pub up_time: Option>, + pub timer: VrrpTimer, + pub last_adv_src: Option, pub statistics: Statistics, } -#[derive(Clone, Copy, Debug, Eq, PartialEq)] -pub enum State { - Initialize, - Backup, - Master, -} +// Protocol state machine. +pub mod fsm { + #[derive(Clone, Copy, Debug, Default, Eq, PartialEq)] + pub enum State { + #[default] + Initialize, + Backup, + Master, + } -#[derive(Clone, Copy, Debug, Eq, PartialEq)] -pub enum Event { - None, - Startup, - Shutdown, - HigherPriorityBackup, - MasterTimeout, - InterfaceUp, - InterfaceDown, - NoPrimaryIpAddress, - PrimaryIpAddress, - NoVirtualIpAddresses, - VirtualIpAddresses, - PreemptHoldTimeout, - LowerPriorityMaster, - OwnerPreempt, + #[derive(Clone, Copy, Debug, Default, Eq, PartialEq)] + pub enum Event { + #[default] + None, + Startup, + Shutdown, + HigherPriorityBackup, + MasterTimeout, + InterfaceUp, + InterfaceDown, + NoPrimaryIpAddress, + PrimaryIpAddress, + NoVirtualIpAddresses, + VirtualIpAddresses, + PreemptHoldTimeout, + LowerPriorityMaster, + OwnerPreempt, + } } -#[derive(Clone, Copy, Debug, Eq, PartialEq)] +#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)] pub enum MasterReason { + #[default] NotMaster, Priority, Preempted, NoResponse, } +#[derive(Debug, Default)] +#[derive(EnumAsInner)] +pub enum VrrpTimer { + #[default] + Null, + AdvTimer(IntervalTask), + MasterDownTimer(TimeoutTask), +} + #[derive(Debug)] pub struct Statistics { pub discontinuity_time: DateTime, @@ -105,55 +107,117 @@ pub struct Statistics { pub priority_zero_pkts_sent: u64, pub invalid_type_pkts_rcvd: u64, pub pkt_length_errors: u64, - pub checksum_errors: u64, - pub version_errors: u64, - pub vrid_errors: u64, - pub ip_ttl_errors: u64, } // ===== impl Instance ===== impl Instance { pub(crate) fn new(vrid: u8) -> Self { - let mut inst = Instance { + Debug::InstanceCreate(vrid).log(); + + Instance { vrid, config: InstanceCfg::default(), - state: InstanceState::new(), - timer: VrrpTimer::Null, - mac_vlan: MacVlanInterface::new(vrid), - }; - inst.set_advert_interval(inst.config.advertise_interval); - inst + state: InstanceState::default(), + mvlan: MacvlanInterface::new(vrid), + } + } + + pub(crate) fn update(&mut self, interface: &InterfaceView) { + if interface.system.is_ready() && self.mvlan.system.is_ready() { + if let Ok(net) = MacvlanNet::new(interface, &self.mvlan) { + self.mvlan.net = Some(net); + self.timer_set(interface); + } + } else { + self.mvlan.net = None; + } } - pub(crate) fn reset_timer(&mut self) { - match self.timer { - VrrpTimer::AdverTimer(ref mut t) => { + pub(crate) fn change_state( + &mut self, + interface: &InterfaceView, + state: fsm::State, + new_master_reason: MasterReason, + ) { + if self.state.state == state { + return; + } + + // Log the state transition. + Debug::InstanceStateChange(self.vrid, self.state.state, state).log(); + + if state == fsm::State::Backup { + for addr in &self.config.virtual_addresses { + southbound::tx::ip_addr_del( + &interface.tx.ibus, + &self.mvlan.name, + *addr, + ); + } + } else if state == fsm::State::Master { + for addr in &self.config.virtual_addresses { + southbound::tx::ip_addr_add( + &interface.tx.ibus, + &self.mvlan.name, + *addr, + ); + } + } + + self.state.state = state; + self.state.new_master_reason = new_master_reason; + self.timer_set(interface); + } + + pub(crate) fn timer_set(&mut self, interface: &InterfaceView) { + match self.state.state { + fsm::State::Initialize => { + self.state.timer = VrrpTimer::Null; + } + fsm::State::Backup => { + let duration = Duration::from_secs( + self.config.master_down_interval() as u64, + ); + let task = tasks::master_down_timer( + self, + duration, + &interface.tx.protocol_input.master_down_timer_tx, + ); + self.state.timer = VrrpTimer::MasterDownTimer(task); + } + fsm::State::Master => { + let Some(net) = &self.mvlan.net else { + return; + }; + let src_ip = interface.system.addresses.first().unwrap().ip(); + let task = tasks::advertisement_interval( + self, + src_ip, + &net.net_tx_packetp, + ); + self.state.timer = VrrpTimer::AdvTimer(task); + } + } + } + + pub(crate) fn timer_reset(&mut self) { + match &mut self.state.timer { + VrrpTimer::AdvTimer(t) => { t.reset(Some(Duration::from_secs( self.config.advertise_interval as u64, ))); } - VrrpTimer::MasterDownTimer(ref mut t) => { + VrrpTimer::MasterDownTimer(t) => { t.reset(Some(Duration::from_secs( - self.state.master_down_interval as u64, + self.config.master_down_interval() as u64, ))); } _ => {} } } - // advert interval directly affects other state parameters - // thus separated in its own function during modification of it. - pub(crate) fn set_advert_interval(&mut self, advertisement_interval: u8) { - self.config.advertise_interval = advertisement_interval; - let skew_time: f32 = (256_f32 - self.config.priority as f32) / 256_f32; - let master_down: u32 = - (3_u32 * self.config.advertise_interval as u32) + skew_time as u32; - self.state.skew_time = skew_time; - self.state.master_down_interval = master_down; - } - - pub(crate) fn adver_vrrp_pkt(&self) -> VrrpHdr { + pub(crate) fn generate_vrrp_packet(&self) -> VrrpHdr { let mut ip_addresses: Vec = vec![]; for addr in self.config.virtual_addresses.clone() { ip_addresses.push(addr.ip()); @@ -176,7 +240,10 @@ impl Instance { packet } - pub(crate) fn adver_ipv4_pkt(&self, src_address: Ipv4Addr) -> Ipv4Hdr { + pub(crate) fn generate_ipv4_packet( + &self, + src_address: Ipv4Addr, + ) -> Ipv4Hdr { // 36 bytes (20 IP + 16 vrrp) // we add 36 to: // 4 * (no of virtual IPs) -> since the number of @@ -196,69 +263,66 @@ impl Instance { protocol: VRRP_PROTO_NUMBER as u8, checksum: 0x00, src_address, - dst_address: Ipv4Addr::new(224, 0, 0, 18), + dst_address: VRRP_MULTICAST_ADDRESS, options: None, padding: None, } } + pub(crate) fn send_vrrp_advertisement(&mut self, src_ip: Ipv4Addr) { + let Some(net) = &self.mvlan.net else { + return; + }; + + let packet = VrrpPacket { + ip: self.generate_ipv4_packet(src_ip), + vrrp: self.generate_vrrp_packet(), + }; + let msg = NetTxPacketMsg::Vrrp { packet }; + let _ = net.net_tx_packetp.send(msg); + } + pub(crate) fn send_gratuitous_arp(&self) { - // send a gratuitous for each of the - // virutal IP addresses - for addr in self.config.virtual_addresses.clone() { - if !self.mac_vlan.is_ready() { - return; - } + let Some(net) = &self.mvlan.net else { + return; + }; + + // Send a gratuitous for each of the virtual IP addresses. + let eth_hdr = EthernetHdr { + ethertype: 0x806, + dst_mac: [0xff; 6], + src_mac: self.mvlan.system.mac_address, + }; + for addr in &self.config.virtual_addresses { let arp_hdr = ArpHdr { hw_type: 1, - // for Ipv4 + // IPv4 proto_type: 0x0800, - // mac address length + // MAC address length hw_length: 6, proto_length: 4, operation: 1, - // sender hw address is virtual mac. + // Sender HW address is virtual mac. // https://datatracker.ietf.org/doc/html/rfc3768#section-7.3 - sender_hw_address: self.mac_vlan.system.mac_address, - sender_proto_address: addr.ip().octets(), - target_hw_address: [0xff, 0xff, 0xff, 0xff, 0xff, 0xff], // broadcast - target_proto_address: addr.ip().octets(), - }; - - let eth_hdr = EthernetHdr { - ethertype: 0x806, - dst_mac: [0xff; 6], - src_mac: self.mac_vlan.system.mac_address, + sender_hw_address: self.mvlan.system.mac_address, + sender_proto_address: addr.ip(), + target_hw_address: [0xff; 6], + target_proto_address: addr.ip(), }; let msg = NetTxPacketMsg::Arp { - ifindex: self.mac_vlan.system.ifindex.unwrap(), + ifindex: self.mvlan.system.ifindex.unwrap(), eth_hdr, arp_hdr, }; - - if let Some(net) = &self.mac_vlan.net { - let _ = net.net_tx_packetp.send(msg); - } + let _ = net.net_tx_packetp.send(msg); } } } -// ===== impl InstanceState ===== - -impl InstanceState { - pub(crate) fn new() -> Self { - InstanceState { - state: State::Initialize, - last_adv_src: None, - up_time: None, - last_event: Event::None, - new_master_reason: MasterReason::NotMaster, - statistics: Default::default(), - skew_time: 0.0, - master_down_interval: 0, - is_owner: false, - } +impl Drop for Instance { + fn drop(&mut self) { + Debug::InstanceDelete(self.vrid).log(); } } @@ -276,10 +340,6 @@ impl Default for Statistics { priority_zero_pkts_sent: 0, invalid_type_pkts_rcvd: 0, pkt_length_errors: 0, - checksum_errors: 0, - version_errors: 0, - vrid_errors: 0, - ip_ttl_errors: 0, } } } diff --git a/holo-vrrp/src/interface.rs b/holo-vrrp/src/interface.rs index 6e93701c..4791a7ee 100644 --- a/holo-vrrp/src/interface.rs +++ b/holo-vrrp/src/interface.rs @@ -8,30 +8,25 @@ // use std::collections::{BTreeMap, BTreeSet}; -use std::sync::Arc; use async_trait::async_trait; +use chrono::{DateTime, Utc}; use holo_protocol::{ InstanceChannelsTx, InstanceShared, MessageReceiver, ProtocolInstance, }; use holo_utils::ibus::IbusMsg; use holo_utils::ip::AddressFamily; use holo_utils::protocol::Protocol; -use holo_utils::socket::{AsyncFd, Socket}; use holo_utils::southbound::InterfaceFlags; -use holo_utils::task::Task; -use holo_utils::{Receiver, Sender, UnboundedSender}; -use ipnetwork::{IpNetwork, Ipv4Network}; +use holo_utils::{Receiver, Sender}; +use ipnetwork::Ipv4Network; use tokio::sync::mpsc; -use tracing::{debug, debug_span, error, error_span}; -use crate::error::{Error, IoError}; -use crate::instance::{Instance, MasterReason, State}; -use crate::packet::{DecodeError, VrrpPacket}; +use crate::error::Error; +use crate::instance::Instance; use crate::tasks::messages::input::{MasterDownTimerMsg, VrrpNetRxPacketMsg}; -use crate::tasks::messages::output::NetTxPacketMsg; use crate::tasks::messages::{ProtocolInputMsg, ProtocolOutputMsg}; -use crate::{events, network, southbound, tasks}; +use crate::{events, southbound}; #[derive(Debug)] pub struct Interface { @@ -41,31 +36,14 @@ pub struct Interface { pub system: InterfaceSys, // Interface VRRP instances. pub instances: BTreeMap, + // Global statistics. + pub statistics: Statistics, // Tx channels. pub tx: InstanceChannelsTx, // Shared data. pub shared: InstanceShared, } -// as far as vrrp is concerned, this will have -// nearly all the features of the normal interface -// but will not hold any VRRP instances etc. -// it is purely meant for being used together with -// a VRRP instance as the MacVlan interface when -// MacVlan is enabled on VRRP. -#[derive(Debug)] -pub struct MacVlanInterface { - // Interface name. - // - // Macvlan interface naming for VRRP will be in the format: - // `mvlan-vrrp-{vrid}` - pub name: String, - // Interface system data. - pub system: InterfaceSys, - // Interface raw sockets and Tx/Rx tasks. - pub net: Option, -} - #[derive(Debug, Default)] pub struct InterfaceSys { // Interface flags. @@ -74,289 +52,77 @@ pub struct InterfaceSys { pub ifindex: Option, // Interface IPv4 addresses. pub addresses: BTreeSet, - // interface Mac Address + // interface MAC Address pub mac_address: [u8; 6], } -#[derive(Debug)] -pub struct MvlanInterfaceNet { - // Raw sockets. - pub socket_vrrp: Arc>, - pub socket_arp: Arc>, - - // Network Tx/Rx tasks. - _net_tx_task: Task<()>, - - // network Tx/Rx tasks. But specifically for VRRP packets. - _vrrp_net_rx_task: Task<()>, - - // Network Tx output channel. - pub net_tx_packetp: UnboundedSender, +#[derive(Debug, Default)] +pub struct Statistics { + pub discontinuity_time: DateTime, + pub checksum_errors: u64, + pub version_errors: u64, + pub vrid_errors: u64, + pub ip_ttl_errors: u64, } #[derive(Clone, Debug)] pub struct ProtocolInputChannelsTx { - // VRRP Packet Tx event. + // VRRP packet Rx event. pub vrrp_net_packet_tx: Sender, - // Master Down event + // Master down timer. pub master_down_timer_tx: Sender, } #[derive(Debug)] pub struct ProtocolInputChannelsRx { - // VRRP Packet Rx event. + // VRRP packet Rx event. pub vrrp_net_packet_rx: Receiver, - // Master Down event + // Master down timer. pub master_down_timer_rx: Receiver, } +pub struct InterfaceView<'a> { + pub name: &'a str, + pub system: &'a mut InterfaceSys, + pub statistics: &'a mut Statistics, + pub tx: &'a InstanceChannelsTx, + pub shared: &'a InstanceShared, +} + // ===== impl Interface ===== impl Interface { - // lets us know if the interface is ready to create a new VRRP - // instance's network elements. - pub(crate) fn is_ready(&self) -> bool { - if self.system.ifindex.is_none() { - return false; - } - if self.system.addresses.is_empty() { - return false; - } - true - } - - pub(crate) fn start_instance(&mut self, vrid: u8) { - let name = format!("mvlan-vrrp-{}", vrid); - let mac_address: [u8; 6] = [0x00, 0x00, 0x5e, 0x00, 0x01, vrid]; - southbound::tx::create_macvlan_iface( - name.clone(), - self.name.clone(), - mac_address, // virtual mac address - &self.tx.ibus, - ); - } - - pub(crate) fn delete_instance(&mut self, vrid: u8) { - let mvlan_ifindex: Option; - if let Some(instance) = self.instances.get(&vrid) { - mvlan_ifindex = instance.mac_vlan.system.ifindex; - } else { - return; - } - - self.instances.remove(&vrid); - if let Some(ifindex) = mvlan_ifindex { - southbound::tx::mvlan_delete(ifindex, &self.tx.ibus); - } - } - - pub(crate) fn change_state( - &mut self, - vrid: u8, - state: State, - new_master_reason: MasterReason, - ) { - if let Some(instance) = self.instances.get_mut(&vrid) { - debug_span!("change-state").in_scope(|| { - if state == State::Initialize { - debug!(%vrid, "state to INITIALIZE."); - instance.state.new_master_reason = new_master_reason; - } else if state == State::Backup { - debug!(%vrid, "state to BACKUP."); - if let Some(ifindex) = instance.mac_vlan.system.ifindex { - for addr in instance.config.virtual_addresses.clone() { - southbound::tx::addr_del( - ifindex, - IpNetwork::V4(addr), - &self.tx.ibus, - ); - } - } - instance.state.new_master_reason = new_master_reason; - } else if state == State::Master { - debug!(%vrid, "state to MASTER."); - if let Some(ifindex) = instance.mac_vlan.system.ifindex { - for addr in instance.config.virtual_addresses.clone() { - southbound::tx::addr_add( - ifindex, - IpNetwork::V4(addr), - &self.tx.ibus, - ); - } - } - instance.state.new_master_reason = new_master_reason; - } - }); - - instance.state.state = state; - self.reset_timer(vrid); - } - } - - pub(crate) fn add_instance_virtual_address( + pub(crate) fn get_instance( &mut self, vrid: u8, - addr: Ipv4Network, - ) { - if let Some(instance) = self.instances.get_mut(&vrid).take() { - instance.config.virtual_addresses.insert(addr); - - if let Some(ifindex) = instance.mac_vlan.system.ifindex { - southbound::tx::addr_add( - ifindex, - IpNetwork::V4(addr), - &self.tx.ibus, - ); - } - self.reset_timer(vrid); - } + ) -> Option<(InterfaceView<'_>, &mut Instance)> { + self.instances.get_mut(&vrid).map(|instance| { + ( + InterfaceView { + name: &self.name, + system: &mut self.system, + statistics: &mut self.statistics, + tx: &self.tx, + shared: &self.shared, + }, + instance, + ) + }) } - pub(crate) fn delete_instance_virtual_address( + pub(crate) fn iter_instances( &mut self, - vrid: u8, - addr: Ipv4Network, - ) { - if let Some(instance) = self.instances.get_mut(&vrid) { - if let Some(ifindex) = instance.mac_vlan.system.ifindex { - // remove address from the instance's configs - instance.config.virtual_addresses.remove(&addr); - - // netlink system call will be initiated to remove the address. - // when response is received, this will also be modified in our - // system's MacVlan - southbound::tx::addr_del( - ifindex, - IpNetwork::V4(addr), - &self.tx.ibus, - ); - } - } - } - - pub(crate) fn send_vrrp_advert(&mut self, vrid: u8) { - if !self.is_ready() { - error_span!("send-vrrp").in_scope(|| { - error!(%vrid, "unable to send vrrp advert. Parent interface has no IP address"); - }); - return; - } - - // check for the exists instance... - if let Some(instance) = self.instances.get_mut(&vrid) - // ...and confirm if the instance's parent Interface has an IP address - && let Some(addr) = self.system.addresses.first() - { - if !instance.mac_vlan.is_ready() { - return; - } - let ip_hdr = instance.adver_ipv4_pkt(addr.ip()); - let vrrp_hdr = instance.adver_vrrp_pkt(); - let pkt = VrrpPacket { - ip: ip_hdr, - vrrp: vrrp_hdr, - }; - - let msg = NetTxPacketMsg::Vrrp { - ifindex: instance.mac_vlan.system.ifindex.unwrap(), - pkt, - }; - if let Some(net) = &instance.mac_vlan.net { - instance.state.statistics.master_transitions += 1; - let _ = net.net_tx_packetp.send(msg); - } - } - } - - // in order to update the details being sent in subsequent - // requests, we will update the timer to have the updated timers with the relevant - // information. - pub(crate) fn reset_timer(&mut self, vrid: u8) { - // we need to make sure the parent interface - // (self) has a valid IP address before setting any timers - // that require us to be part of a multicast - if self.is_ready() { - tasks::set_timer( - self, - vrid, - self.tx.protocol_input.master_down_timer_tx.clone(), - ); - } - } - - // creates the MvlanInterfaceNet for the instance of said - // vrid. Must be done here to get some interface specifics. - // should always be called after vrification of self.is_ready() - pub(crate) fn net_create(&mut self, vrid: u8) { - let net = MvlanInterfaceNet::new(self, vrid) - .expect("Failed to intialize VRRP tasks"); - - if let Some(instance) = self.instances.get_mut(&vrid) { - // check if the macvlan is ready for the - // network items to be created - if instance.mac_vlan.is_ready() { - instance.mac_vlan.net = Some(net); - } - } - } - - // removes the Macvlan interface's network from the instance - // where vrid==vrid - pub(crate) fn net_remove(&mut self, vrid: u8) { - if let Some(instance) = self.instances.get_mut(&vrid) { - instance.mac_vlan.net = None; - } - } - - // reloads the networks that are in the instance(s) of this Interface - // 'reloads' means we reset the network to their correct state depending on what - // we get from self.is_ready(). This should be called when we have an IP address - // modification (addition / deletion) on either an instance's MacVlan or the - // parent interface. - // - // if `vrid` is None, we will reload all the instances and not a specific vrid. - pub(crate) fn net_reload(&mut self, vrid: Option) { - let mut vrids: Vec = vec![]; - - // collects the vrids. if vrid is None, we collect all the - // vrids - if let Some(vrid) = vrid { - vrids.push(vrid) - } else { - for vrid in self.instances.keys() { - vrids.push(*vrid); - } - } - - if self.is_ready() { - // (re-)create all the relevant networks. - for vrid in vrids { - self.net_create(vrid); - self.reset_timer(vrid); - } - } else { - // remove the networks. Will automatically remove the - // timers as they are part of the MacVlanInterface's net - for vrid in vrids { - self.net_remove(vrid); - } - } - } - - pub(crate) fn add_error_stats(&mut self, error: DecodeError) { - match error { - DecodeError::ChecksumError(vrid) => { - if let Some(instance) = self.instances.get_mut(&vrid) { - instance.state.statistics.checksum_errors += 1; - } - } - DecodeError::PacketLengthError(vrid) => { - if let Some(instance) = self.instances.get_mut(&vrid) { - instance.state.statistics.pkt_length_errors += 1; - } - } - _ => {} - } + ) -> (InterfaceView<'_>, impl Iterator) { + ( + InterfaceView { + name: &self.name, + system: &mut self.system, + statistics: &mut self.statistics, + tx: &self.tx, + shared: &self.shared, + }, + self.instances.values_mut(), + ) } } @@ -374,19 +140,18 @@ impl ProtocolInstance for Interface { shared: InstanceShared, tx: InstanceChannelsTx, ) -> Interface { - // TODO: proper error handling Interface { name, system: Default::default(), instances: Default::default(), + statistics: Default::default(), tx, shared, } } async fn init(&mut self) { - // request for details of the master interface - // to be sent so we can update our details. + // Request system information about the interface. let _ = self.tx.ibus.send(IbusMsg::InterfaceQuery { ifname: self.name.clone(), af: Some(AddressFamily::Ipv4), @@ -405,6 +170,7 @@ impl ProtocolInstance for Interface { ProtocolInputMsg::VrrpNetRxPacket(msg) => { events::process_vrrp_packet(self, msg.src, msg.packet) } + // Master down timer. ProtocolInputMsg::MasterDownTimer(msg) => { events::handle_master_down_timer(self, msg.vrid) } @@ -436,71 +202,18 @@ impl ProtocolInstance for Interface { } } -// ==== impl MacVlanInterface ==== -impl MacVlanInterface { - pub(crate) fn is_ready(&self) -> bool { - // return true if the ifindex exists - self.system.ifindex.is_some() - } +// ===== impl InterfaceSys ===== - pub fn new(vrid: u8) -> Self { - let name = format!("mvlan-vrrp-{}", vrid); - Self { - name, - system: InterfaceSys::default(), - net: None, +impl InterfaceSys { + pub(crate) fn is_ready(&self) -> bool { + if self.ifindex.is_none() { + return false; + } + if self.addresses.is_empty() { + return false; } - } -} - -impl MvlanInterfaceNet { - fn new(parent_iface: &Interface, vrid: u8) -> Result { - let instance = parent_iface.instances.get(&vrid).unwrap(); - let ifname = &instance.mac_vlan.name; - let instance_channels_tx = &parent_iface.tx; - - let socket_vrrp_rx = network::socket_vrrp_rx(parent_iface) - .map_err(IoError::SocketError) - .and_then(|socket| { - AsyncFd::new(socket).map_err(IoError::SocketError) - }) - .map(Arc::new)?; - - let socket_vrrp_tx = network::socket_vrrp_tx(parent_iface, vrid) - .map_err(IoError::SocketError) - .and_then(|socket| { - AsyncFd::new(socket).map_err(IoError::SocketError) - }) - .map(Arc::new)?; - - let socket_arp = network::socket_arp(ifname) - .map_err(IoError::SocketError) - .and_then(|socket| { - AsyncFd::new(socket).map_err(IoError::SocketError) - }) - .map(Arc::new)?; - - // Start network Tx/Rx tasks. - let (net_tx_packetp, net_tx_packetc) = mpsc::unbounded_channel(); - let net_tx_task = tasks::net_tx( - socket_vrrp_tx, - socket_arp.clone(), - net_tx_packetc, - #[cfg(feature = "testing")] - &instance_channels_tx.protocol_output, - ); - let vrrp_net_rx_task = tasks::vrrp_net_rx( - socket_vrrp_rx.clone(), - &instance_channels_tx.protocol_input.vrrp_net_packet_tx, - ); - Ok(Self { - socket_vrrp: socket_vrrp_rx, - socket_arp, - _net_tx_task: net_tx_task, - _vrrp_net_rx_task: vrrp_net_rx_task, - net_tx_packetp, - }) + true } } diff --git a/holo-vrrp/src/lib.rs b/holo-vrrp/src/lib.rs index 34fe3bc0..903606a0 100644 --- a/holo-vrrp/src/lib.rs +++ b/holo-vrrp/src/lib.rs @@ -19,6 +19,7 @@ pub mod error; pub mod events; pub mod instance; pub mod interface; +pub mod macvlan; pub mod network; pub mod northbound; pub mod packet; diff --git a/holo-vrrp/src/macvlan.rs b/holo-vrrp/src/macvlan.rs new file mode 100644 index 00000000..3ae4fa37 --- /dev/null +++ b/holo-vrrp/src/macvlan.rs @@ -0,0 +1,110 @@ +// +// 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::sync::Arc; + +use holo_utils::socket::{AsyncFd, Socket}; +use holo_utils::task::Task; +use holo_utils::UnboundedSender; +use tokio::sync::mpsc; + +use crate::error::IoError; +use crate::interface::{InterfaceSys, InterfaceView}; +use crate::tasks::messages::output::NetTxPacketMsg; +use crate::{network, tasks}; + +#[derive(Debug)] +pub struct MacvlanInterface { + // Interface name. + pub name: String, + // Interface system data. + pub system: InterfaceSys, + // Interface raw sockets and Tx/Rx tasks. + pub net: Option, +} + +#[derive(Debug)] +pub struct MacvlanNet { + // Raw sockets. + pub socket_vrrp_tx: Arc>, + pub socket_vrrp_rx: Arc>, + pub socket_arp: Arc>, + // Network Tx/Rx tasks. + _net_tx_task: Task<()>, + _vrrp_net_rx_task: Task<()>, + // Network Tx output channel. + pub net_tx_packetp: UnboundedSender, +} + +// ==== impl MacvlanInterface ==== + +impl MacvlanInterface { + pub(crate) fn new(vrid: u8) -> Self { + let name = format!("mvlan-vrrp-{}", vrid); + Self { + name, + system: InterfaceSys::default(), + net: None, + } + } +} + +// ==== impl MacvlanNet ==== + +impl MacvlanNet { + pub(crate) fn new( + parent_iface: &InterfaceView, + mvlan: &MacvlanInterface, + ) -> Result { + let instance_channels_tx = &parent_iface.tx; + + // Create raw sockets. + let socket_vrrp_rx = network::socket_vrrp_rx(parent_iface) + .map_err(IoError::SocketError) + .and_then(|socket| { + AsyncFd::new(socket).map_err(IoError::SocketError) + }) + .map(Arc::new)?; + let socket_vrrp_tx = network::socket_vrrp_tx(mvlan) + .map_err(IoError::SocketError) + .and_then(|socket| { + AsyncFd::new(socket).map_err(IoError::SocketError) + }) + .map(Arc::new)?; + let socket_arp = network::socket_arp(&mvlan.name) + .map_err(IoError::SocketError) + .and_then(|socket| { + AsyncFd::new(socket).map_err(IoError::SocketError) + }) + .map(Arc::new)?; + + // Start network Tx/Rx tasks. + let (net_tx_packetp, net_tx_packetc) = mpsc::unbounded_channel(); + let net_tx_task = tasks::net_tx( + socket_vrrp_tx.clone(), + socket_arp.clone(), + net_tx_packetc, + #[cfg(feature = "testing")] + &instance_channels_tx.protocol_output, + ); + let vrrp_net_rx_task = tasks::vrrp_net_rx( + socket_vrrp_rx.clone(), + &instance_channels_tx.protocol_input.vrrp_net_packet_tx, + ); + + Ok(Self { + socket_vrrp_tx, + socket_vrrp_rx, + socket_arp, + _net_tx_task: net_tx_task, + _vrrp_net_rx_task: vrrp_net_rx_task, + net_tx_packetp, + }) + } +} diff --git a/holo-vrrp/src/network.rs b/holo-vrrp/src/network.rs index 7beca351..87532846 100644 --- a/holo-vrrp/src/network.rs +++ b/holo-vrrp/src/network.rs @@ -7,6 +7,7 @@ // See: https://nlnet.nl/NGI0 // +use std::io::IoSlice; use std::os::fd::AsRawFd; use std::sync::Arc; @@ -14,46 +15,48 @@ use bytes::BufMut; use holo_utils::socket::{AsyncFd, Socket}; use holo_utils::{capabilities, Sender, UnboundedReceiver}; use libc::{AF_PACKET, ETH_P_ARP}; -use nix::sys::socket::{self, sendto, LinkAddr, MsgFlags, SockaddrLike}; +use nix::sys::socket::{self, LinkAddr, SockaddrIn, SockaddrLike}; use socket2::{Domain, Protocol, Type}; use tokio::sync::mpsc::error::SendError; -use crate::consts::{VRRP_HDR_MAX, VRRP_MULTICAST_ADDRESS, VRRP_PROTO_NUMBER}; +use crate::consts::{ + ARP_PROTOCOL_NUMBER, VRRP_MULTICAST_ADDRESS, VRRP_PROTO_NUMBER, +}; +use crate::debug::Debug; use crate::error::IoError; -use crate::interface::Interface; +use crate::interface::InterfaceView; +use crate::macvlan::MacvlanInterface; use crate::packet::{ArpHdr, EthernetHdr, Ipv4Hdr, VrrpHdr, VrrpPacket}; use crate::tasks::messages::input::VrrpNetRxPacketMsg; use crate::tasks::messages::output::NetTxPacketMsg; -pub fn socket_vrrp_tx( - interface: &Interface, - vrid: u8, +// ===== global functions ===== + +pub(crate) fn socket_vrrp_tx( + mvlan: &MacvlanInterface, ) -> Result { #[cfg(not(feature = "testing"))] { - let instance = interface.instances.get(&vrid).unwrap(); - let sock = capabilities::raise(|| { + let socket = capabilities::raise(|| { Socket::new( Domain::IPV4, Type::RAW, Some(Protocol::from(VRRP_PROTO_NUMBER)), ) })?; - sock.set_nonblocking(true)?; - if let Some(addr) = instance.mac_vlan.system.addresses.first() { - sock.set_multicast_if_v4(&addr.ip())?; - } - - sock.set_header_included(true)?; - - // Confirm if we should bind to the primary interface's address... - // bind it to the primary interface's name + socket.set_nonblocking(true)?; + socket.set_reuse_address(true)?; + socket.set_multicast_if_v4( + &mvlan.system.addresses.first().unwrap().ip(), + )?; + socket.set_header_included(true)?; + socket.set_multicast_ttl_v4(255)?; + socket.set_tos(libc::IPTOS_PREC_INTERNETCONTROL as u32)?; capabilities::raise(|| { - sock.bind_device(Some(instance.mac_vlan.name.as_bytes())) + socket.bind_device(Some(mvlan.name.as_bytes())) })?; - let _ = sock.set_reuse_address(true); - Ok(sock) + Ok(socket) } #[cfg(feature = "testing")] { @@ -61,21 +64,28 @@ pub fn socket_vrrp_tx( } } -pub fn socket_vrrp_rx(iface: &Interface) -> Result { +pub(crate) fn socket_vrrp_rx( + interface: &InterfaceView, +) -> Result { #[cfg(not(feature = "testing"))] { - let sock = capabilities::raise(|| { + let socket = capabilities::raise(|| { Socket::new( Domain::IPV4, Type::RAW, Some(Protocol::from(VRRP_PROTO_NUMBER)), ) })?; - capabilities::raise(|| sock.bind_device(Some(iface.name.as_bytes())))?; - sock.set_nonblocking(true)?; - join_multicast(&sock, iface)?; + capabilities::raise(|| { + socket.bind_device(Some(interface.name.as_bytes())) + })?; + socket.set_nonblocking(true)?; + socket.join_multicast_v4( + &VRRP_MULTICAST_ADDRESS, + &interface.system.addresses.first().unwrap().ip(), + )?; - Ok(sock) + Ok(socket) } #[cfg(feature = "testing")] { @@ -83,21 +93,20 @@ pub fn socket_vrrp_rx(iface: &Interface) -> Result { } } -pub fn socket_arp(ifname: &str) -> Result { +pub(crate) fn socket_arp(ifname: &str) -> Result { #[cfg(not(feature = "testing"))] { - let sock = capabilities::raise(|| { + let socket = capabilities::raise(|| { Socket::new( Domain::PACKET, Type::RAW, Some(Protocol::from(ETH_P_ARP)), ) })?; - capabilities::raise(|| { - let _ = sock.bind_device(Some(ifname.as_bytes())); - }); - let _ = sock.set_broadcast(true); - Ok(sock) + capabilities::raise(|| socket.bind_device(Some(ifname.as_bytes())))?; + socket.set_broadcast(true)?; + + Ok(socket) } #[cfg(feature = "testing")] { @@ -106,56 +115,49 @@ pub fn socket_arp(ifname: &str) -> Result { } #[cfg(not(feature = "testing"))] -pub(crate) async fn send_packet_vrrp( - sock: &AsyncFd, - ifindex: u32, - pkt: VrrpPacket, +async fn send_packet_vrrp( + socket: &AsyncFd, + packet: VrrpPacket, ) -> Result { - use crate::consts::IP_VRRP_HDR_MAX; - - unsafe { - let mut sa = libc::sockaddr_ll { - sll_family: libc::AF_INET as u16, - sll_protocol: (VRRP_PROTO_NUMBER as u16).to_be(), - sll_ifindex: ifindex as i32, - sll_hatype: 0, - sll_pkttype: 0, - sll_halen: 0, - sll_addr: [0; 8], - }; + Debug::PacketTx(&packet.vrrp).log(); - let ptr_sockaddr = std::mem::transmute::< - *mut libc::sockaddr_ll, - *mut libc::sockaddr, - >(&mut sa); - let buf: &[u8] = &pkt.encode(); + // Encode packet. + let buf = packet.encode(); - match libc::sendto( - sock.as_raw_fd(), - buf.as_ptr().cast(), - std::cmp::min(buf.len(), IP_VRRP_HDR_MAX), - 0, - ptr_sockaddr, - std::mem::size_of_val(&sa) as u32, - ) { - -1 => Err(IoError::SendError(std::io::Error::last_os_error())), - fd => Ok(fd as usize), - } - } + // Send packet. + let iov = [IoSlice::new(&buf)]; + let sockaddr: SockaddrIn = + std::net::SocketAddrV4::new(VRRP_MULTICAST_ADDRESS, 0).into(); + socket + .async_io(tokio::io::Interest::WRITABLE, |socket| { + socket::sendmsg( + socket.as_raw_fd(), + &iov, + &[], + socket::MsgFlags::empty(), + Some(&sockaddr), + ) + .map_err(|errno| errno.into()) + }) + .await + .map_err(IoError::SendError) } #[cfg(not(feature = "testing"))] -pub async fn send_packet_arp( - sock: &AsyncFd, +async fn send_packet_arp( + socket: &AsyncFd, ifindex: u32, eth_hdr: EthernetHdr, arp_hdr: ArpHdr, ) -> Result { - use crate::consts::ARP_PROTOCOL_NUMBER; + Debug::ArpTx(&arp_hdr.sender_proto_address).log(); + // Encode packet. let mut buf = eth_hdr.encode(); buf.put(arp_hdr.encode()); + // Send packet. + let iov = [IoSlice::new(&buf)]; let mut sll = libc::sockaddr_ll { sll_family: AF_PACKET as u16, sll_protocol: ARP_PROTOCOL_NUMBER.to_be(), @@ -167,28 +169,23 @@ pub async fn send_packet_arp( }; sll.sll_addr[..6].copy_from_slice(ð_hdr.dst_mac); let sll_len = size_of_val(&sll) as libc::socklen_t; - let saddr = unsafe { + let sockaddr = unsafe { LinkAddr::from_raw(&sll as *const _ as *const _, Some(sll_len)) } .unwrap(); - match sendto(sock.as_raw_fd(), &buf, &saddr, MsgFlags::empty()) { - Ok(res) => Ok(res), - Err(errno) => Err(IoError::SendError(errno.into())), - } -} - -// for joining the VRRP multicast -#[cfg(not(feature = "testing"))] -pub fn join_multicast( - sock: &Socket, - iface: &Interface, -) -> Result<(), std::io::Error> { - let sock = socket2::SockRef::from(sock); - if let Some(addr) = iface.system.addresses.first() { - let ip = addr.ip(); - return sock.join_multicast_v4(&VRRP_MULTICAST_ADDRESS, &ip); - } - Err(std::io::Error::last_os_error()) + socket + .async_io(tokio::io::Interest::WRITABLE, |socket| { + socket::sendmsg( + socket.as_raw_fd(), + &iov, + &[], + socket::MsgFlags::empty(), + Some(&sockaddr), + ) + .map_err(|errno| errno.into()) + }) + .await + .map_err(IoError::SendError) } #[cfg(not(feature = "testing"))] @@ -199,9 +196,8 @@ pub(crate) async fn write_loop( ) { while let Some(msg) = net_tx_packetc.recv().await { match msg { - NetTxPacketMsg::Vrrp { ifindex, pkt } => { - if let Err(error) = - send_packet_vrrp(&socket_vrrp, ifindex, pkt).await + NetTxPacketMsg::Vrrp { packet } => { + if let Err(error) = send_packet_vrrp(&socket_vrrp, packet).await { error.log(); } @@ -227,21 +223,21 @@ pub(crate) async fn vrrp_read_loop( socket_vrrp: Arc>, vrrp_net_packet_rxp: Sender, ) -> Result<(), SendError> { - let mut buf = [0u8; VRRP_HDR_MAX]; + let mut buf = [0u8; 16384]; loop { match socket_vrrp - .async_io(tokio::io::Interest::READABLE, |sock| { + .async_io(tokio::io::Interest::READABLE, |socket| { match socket::recv( - sock.as_raw_fd(), + socket.as_raw_fd(), &mut buf, socket::MsgFlags::empty(), ) { Ok(msg) => { let data = &buf[0..msg]; - // since ip header length is given in number of words + // Since IP header length is given in number of words // (4 bytes per word), we multiply by 4 to get the actual - // number of bytes + // number of bytes. let ip_header_len = ((data[0] & 0x0f) * 4) as usize; let ip_pkt = @@ -262,7 +258,7 @@ pub(crate) async fn vrrp_read_loop( vrrp_net_packet_rxp.send(msg).await.unwrap(); } Err(error) if error.kind() == std::io::ErrorKind::Interrupted => { - // retry if the syscall was interrupted + // Retry if the syscall was interrupted (EINTR). continue; } Err(error) => { diff --git a/holo-vrrp/src/northbound/configuration.rs b/holo-vrrp/src/northbound/configuration.rs index 05894478..469cd175 100644 --- a/holo-vrrp/src/northbound/configuration.rs +++ b/holo-vrrp/src/northbound/configuration.rs @@ -20,8 +20,9 @@ use holo_northbound::yang::interfaces; use holo_utils::yang::DataNodeRefExt; use ipnetwork::Ipv4Network; -use crate::instance::{Event as LastEvent, Instance}; +use crate::instance::{fsm, Instance, MasterReason}; use crate::interface::Interface; +use crate::southbound; #[derive(Debug, Default, EnumAsInner)] pub enum ListEntry { @@ -36,16 +37,11 @@ pub enum Resource {} #[derive(Debug, Eq, Ord, PartialEq, PartialOrd)] pub enum Event { - // instance events InstanceStart { vrid: u8 }, InstanceDelete { vrid: u8 }, - - // virtual address events VirtualAddressCreate { vrid: u8, addr: Ipv4Network }, VirtualAddressDelete { vrid: u8, addr: Ipv4Network }, - - // priority events - PriorityUpdate { vrid: u8, priority: u8 }, + ResetTimer { vrid: u8 }, } pub static VALIDATION_CALLBACKS: Lazy = @@ -71,7 +67,7 @@ fn load_callbacks() -> Callbacks { .create_apply(|interface, args| { let vrid = args.dnode.get_u8_relative("./vrid").unwrap(); let mut instance = Instance::new(vrid); - instance.state.last_event = LastEvent::Startup; + instance.state.last_event = fsm::Event::Startup; interface.instances.insert(vrid, instance); let event_queue = args.event_queue; @@ -79,6 +75,7 @@ fn load_callbacks() -> Callbacks { }) .delete_apply(|_interface, args| { let vrid = args.list_entry.into_vrid().unwrap(); + let event_queue = args.event_queue; event_queue.insert(Event::InstanceDelete { vrid }); }) @@ -107,12 +104,15 @@ fn load_callbacks() -> Callbacks { instance.config.preempt = preempt; }) .path(interfaces::interface::ipv4::vrrp::vrrp_instance::priority::PATH) - .modify_apply(|_interface, args| { + .modify_apply(|interface, args| { let vrid = args.list_entry.into_vrid().unwrap(); - let event_queue = args.event_queue; + let instance = interface.instances.get_mut(&vrid).unwrap(); + let priority = args.dnode.get_u8(); + instance.config.priority = priority; - event_queue.insert(Event::PriorityUpdate { vrid, priority }); + let event_queue = args.event_queue; + event_queue.insert(Event::ResetTimer { vrid }); }) .path(interfaces::interface::ipv4::vrrp::vrrp_instance::advertise_interval_sec::PATH) .modify_apply(|interface, args| { @@ -126,16 +126,22 @@ fn load_callbacks() -> Callbacks { // Nothing to do. }) .path(interfaces::interface::ipv4::vrrp::vrrp_instance::virtual_ipv4_addresses::virtual_ipv4_address::PATH) - .create_apply(|_interface, args| { + .create_apply(|interface, args| { let vrid = args.list_entry.into_vrid().unwrap(); + let instance = interface.instances.get_mut(&vrid).unwrap(); + let addr = args.dnode.get_prefix4_relative("ipv4-address").unwrap(); + instance.config.virtual_addresses.insert(addr); + let event_queue = args.event_queue; - event_queue.insert ( - Event::VirtualAddressCreate { vrid, addr } - ); + event_queue.insert(Event::VirtualAddressCreate { vrid, addr }); }) - .delete_apply(|_interface, args| { + .delete_apply(|interface, args| { let (vrid, addr) = args.list_entry.into_virtual_ipv4_addr().unwrap(); + let instance = interface.instances.get_mut(&vrid).unwrap(); + + instance.config.virtual_addresses.remove(&addr); + let event_queue = args.event_queue; event_queue.insert(Event::VirtualAddressDelete { vrid, addr }); }) @@ -179,41 +185,73 @@ impl Provider for Interface { async fn process_event(&mut self, event: Event) { match event { - // instance events Event::InstanceStart { vrid } => { - self.start_instance(vrid); + let (interface, instance) = self.get_instance(vrid).unwrap(); + + // Create macvlan interface. + let virtual_mac_addr: [u8; 6] = + [0x00, 0x00, 0x5e, 0x00, 0x01, vrid]; + southbound::tx::mvlan_create( + &interface.tx.ibus, + interface.name.to_owned(), + instance.mvlan.name.clone(), + virtual_mac_addr, + ); // reminder to remove the following line. // currently up due to state not being properly maintained on startup. - self.change_state( - vrid, - crate::instance::State::Backup, - crate::instance::MasterReason::NotMaster, + instance.change_state( + &interface, + fsm::State::Backup, + MasterReason::NotMaster, ); } Event::InstanceDelete { vrid } => { - self.delete_instance(vrid); - } + let instance = self.instances.remove(&vrid).unwrap(); - // virtual address events + // Delete macvlan interface. + southbound::tx::mvlan_delete( + &self.tx.ibus, + &instance.mvlan.name, + ); + } Event::VirtualAddressCreate { vrid, addr } => { - self.add_instance_virtual_address(vrid, addr); + let (interface, instance) = self.get_instance(vrid).unwrap(); + southbound::tx::ip_addr_add( + &interface.tx.ibus, + &instance.mvlan.name, + addr, + ); + instance.timer_set(&interface); } Event::VirtualAddressDelete { vrid, addr } => { - self.delete_instance_virtual_address(vrid, addr); + let (interface, instance) = self.get_instance(vrid).unwrap(); + southbound::tx::ip_addr_del( + &interface.tx.ibus, + &instance.mvlan.name, + addr, + ); } - - // priority events - Event::PriorityUpdate { vrid, priority } => { - if let Some(instance) = self.instances.get_mut(&vrid) { - instance.config.priority = priority; - self.reset_timer(vrid); - } + Event::ResetTimer { vrid } => { + let (_, instance) = self.get_instance(vrid).unwrap(); + instance.timer_reset(); } } } } +// ===== configuration helpers ===== + +impl InstanceCfg { + pub(crate) const fn master_down_interval(&self) -> u32 { + (3 * self.advertise_interval as u32) + self.skew_time() as u32 + } + + pub(crate) const fn skew_time(&self) -> f32 { + (256_f32 - self.priority as f32) / 256_f32 + } +} + // ===== configuration defaults ===== impl Default for InstanceCfg { diff --git a/holo-vrrp/src/northbound/state.rs b/holo-vrrp/src/northbound/state.rs index 265f0d11..e9606327 100644 --- a/holo-vrrp/src/northbound/state.rs +++ b/holo-vrrp/src/northbound/state.rs @@ -50,8 +50,7 @@ fn load_callbacks() -> Callbacks { is_owner: None, last_adv_source: instance.state.last_adv_src.map(std::convert::Into::into).map(Cow::Owned).ignore_in_testing(), up_datetime: instance.state.up_time.as_ref().map(Cow::Borrowed).ignore_in_testing(), - // TODO - master_down_interval: None, + master_down_interval: instance.state.timer.as_master_down_timer().map(|task| task.remaining().as_millis() as u32 / 10).ignore_in_testing(), // TODO skew_time: None, last_event: Some(instance.state.last_event.to_yang()).ignore_in_testing(), diff --git a/holo-vrrp/src/northbound/yang.rs b/holo-vrrp/src/northbound/yang.rs index 6dd20f9d..548e1748 100644 --- a/holo-vrrp/src/northbound/yang.rs +++ b/holo-vrrp/src/northbound/yang.rs @@ -11,55 +11,59 @@ use std::borrow::Cow; use holo_yang::ToYang; -use crate::instance::{Event, MasterReason, State}; +use crate::instance::{fsm, MasterReason}; // ===== ToYang implementations ===== -impl ToYang for State { +impl ToYang for fsm::State { fn to_yang(&self) -> Cow<'static, str> { match self { - State::Initialize => "ietf-vrrp:initialize".into(), - State::Backup => "ietf-vrrp:backup".into(), - State::Master => "ietf-vrrp:master".into(), + fsm::State::Initialize => "ietf-vrrp:initialize".into(), + fsm::State::Backup => "ietf-vrrp:backup".into(), + fsm::State::Master => "ietf-vrrp:master".into(), } } } -impl ToYang for Event { +impl ToYang for fsm::Event { fn to_yang(&self) -> Cow<'static, str> { match self { - Event::None => "ietf-vrrp:vrrp-event-none".into(), - Event::Startup => "ietf-vrrp:vrrp-event-startup".into(), - Event::Shutdown => "ietf-vrrp:vrrp-event-shutdown".into(), - Event::HigherPriorityBackup => { + fsm::Event::None => "ietf-vrrp:vrrp-event-none".into(), + fsm::Event::Startup => "ietf-vrrp:vrrp-event-startup".into(), + fsm::Event::Shutdown => "ietf-vrrp:vrrp-event-shutdown".into(), + fsm::Event::HigherPriorityBackup => { "ietf-vrrp:vrrp-event-higher-priority-backup".into() } - Event::MasterTimeout => { + fsm::Event::MasterTimeout => { "ietf-vrrp:vrrp-event-master-timeout".into() } - Event::InterfaceUp => "ietf-vrrp:vrrp-event-interface-up".into(), - Event::InterfaceDown => { + fsm::Event::InterfaceUp => { + "ietf-vrrp:vrrp-event-interface-up".into() + } + fsm::Event::InterfaceDown => { "ietf-vrrp:vrrp-event-interface-down".into() } - Event::NoPrimaryIpAddress => { + fsm::Event::NoPrimaryIpAddress => { "ietf-vrrp:vrrp-event-no-primary-ip-address".into() } - Event::PrimaryIpAddress => { + fsm::Event::PrimaryIpAddress => { "ietf-vrrp:vrrp-event-primary-ip-address".into() } - Event::NoVirtualIpAddresses => { + fsm::Event::NoVirtualIpAddresses => { "ietf-vrrp:vrrp-event-no-virtual-ip-addresses".into() } - Event::VirtualIpAddresses => { + fsm::Event::VirtualIpAddresses => { "ietf-vrrp:vrrp-event-virtual-ip-addresses".into() } - Event::PreemptHoldTimeout => { + fsm::Event::PreemptHoldTimeout => { "ietf-vrrp:vrrp-event-preempt-hold-timeout".into() } - Event::LowerPriorityMaster => { + fsm::Event::LowerPriorityMaster => { "ietf-vrrp:vrrp-event-lower-priority-master".into() } - Event::OwnerPreempt => "ietf-vrrp:vrrp-event-owner-preempt".into(), + fsm::Event::OwnerPreempt => { + "ietf-vrrp:vrrp-event-owner-preempt".into() + } } } } diff --git a/holo-vrrp/src/packet.rs b/holo-vrrp/src/packet.rs index b4eca140..42924b9f 100644 --- a/holo-vrrp/src/packet.rs +++ b/holo-vrrp/src/packet.rs @@ -14,7 +14,6 @@ use holo_utils::bytes::{BytesExt, BytesMutExt}; use serde::{Deserialize, Serialize}; use crate::consts::*; -use crate::error::{self, Error, GlobalError, VirtualRouterError}; // Type aliases. pub type DecodeResult = Result; @@ -54,12 +53,12 @@ pub struct VrrpHdr { pub adver_int: u8, pub checksum: u16, pub ip_addresses: Vec, - - // the following two are only used for backward compatibility. + // The following two are only used for backward compatibility. pub auth_data: u32, pub auth_data2: u32, } +// // IP packet header // // 0 1 2 3 @@ -97,7 +96,7 @@ pub struct Ipv4Hdr { pub padding: Option, } -#[derive(Clone, Debug, Eq, PartialEq)] +#[derive(Clone, Copy, Debug, Eq, PartialEq)] #[derive(Deserialize, Serialize)] pub struct EthernetHdr { pub dst_mac: [u8; 6], @@ -113,10 +112,10 @@ pub struct ArpHdr { pub hw_length: u8, pub proto_length: u8, pub operation: u16, - pub sender_hw_address: [u8; 6], // src mac - pub sender_proto_address: [u8; 4], // src ip - pub target_hw_address: [u8; 6], // src mac - pub target_proto_address: [u8; 4], // src ip + pub sender_hw_address: [u8; 6], + pub sender_proto_address: Ipv4Addr, + pub target_hw_address: [u8; 6], + pub target_proto_address: Ipv4Addr, } #[derive(Clone, Debug, Eq, PartialEq)] @@ -129,29 +128,8 @@ pub struct VrrpPacket { #[derive(Debug, Eq, PartialEq)] #[derive(Deserialize, Serialize)] pub enum DecodeError { - ChecksumError(u8), // u8 is the vrid - PacketLengthError(u8), // u8 is the vrid - IpTtlError(u8), // u8 is the vrid - VersionError, -} - -impl DecodeError { - pub fn err(&self) -> error::Error { - match self { - DecodeError::ChecksumError(_) => { - Error::GlobalError(GlobalError::ChecksumError) - } - DecodeError::PacketLengthError(_) => { - Error::VirtualRouterError(VirtualRouterError::PacketLengthError) - } - DecodeError::IpTtlError(_) => { - Error::GlobalError(GlobalError::IpTtlError) - } - DecodeError::VersionError => { - Error::GlobalError(GlobalError::VersionError) - } - } - } + ChecksumError, + PacketLengthError { vrid: u8 }, } // ===== impl Packet ===== @@ -179,7 +157,6 @@ impl VrrpHdr { // Decodes VRRP packet from a bytes buffer. pub fn decode(data: &[u8]) -> DecodeResult { - // 1. pkt length verification let pkt_size = data.len(); let mut buf: Bytes = Bytes::copy_from_slice(data); @@ -196,7 +173,7 @@ impl VrrpHdr { || count_ip as usize > VRRP_IP_COUNT_MAX || (count_ip * 4) + 16 != pkt_size as u8 { - return Err(DecodeError::PacketLengthError(vrid)); + return Err(DecodeError::PacketLengthError { vrid }); } let checksum = buf.get_u16(); @@ -204,7 +181,7 @@ impl VrrpHdr { // confirm checksum. checksum position is the third item in 16 bit words let calculated_checksum = checksum::calculate(data, 3); if calculated_checksum != checksum { - return Err(DecodeError::ChecksumError(vrid)); + return Err(DecodeError::ChecksumError); } let mut ip_addresses: Vec = vec![]; @@ -365,50 +342,27 @@ impl ArpHdr { buf.put_u8(self.hw_length); buf.put_u8(self.proto_length); buf.put_u16(self.operation); - - for x in self.sender_hw_address { - buf.put_u8(x); - } - for x in self.sender_proto_address { - buf.put_u8(x); - } - for x in self.target_hw_address { - buf.put_u8(x) - } - for x in self.target_proto_address { - buf.put_u8(x) - } + buf.put_slice(&self.sender_hw_address); + buf.put_ipv4(&self.sender_proto_address); + buf.put_slice(&self.target_hw_address); + buf.put_ipv4(&self.target_proto_address); buf } pub fn decode(data: &[u8]) -> DecodeResult { let mut buf = Bytes::copy_from_slice(data); + let mut sender_hw_address: [u8; 6] = [0; 6]; + let mut target_hw_address: [u8; 6] = [0; 6]; let hw_type = buf.get_u16(); let proto_type = buf.get_u16(); let hw_length = buf.get_u8(); let proto_length = buf.get_u8(); let operation = buf.get_u16(); - - let sender_hw_address: [u8; 6] = [0_u8; 6]; - for mut _x in &sender_hw_address { - _x = &buf.get_u8(); - } - - let sender_proto_address: [u8; 4] = [0_u8; 4]; - for mut _x in &sender_proto_address { - _x = &buf.get_u8(); - } - - let target_hw_address: [u8; 6] = [0_u8; 6]; - for mut _x in &target_hw_address { - _x = &buf.get_u8(); - } - - let target_proto_address: [u8; 4] = [0_u8; 4]; - for mut _x in &target_proto_address { - _x = &buf.get_u8(); - } + buf.copy_to_slice(&mut sender_hw_address); + let sender_proto_address = buf.get_ipv4(); + buf.copy_to_slice(&mut target_hw_address); + let target_proto_address = buf.get_ipv4(); Ok(Self { hw_type, @@ -457,13 +411,3 @@ pub mod checksum { result } } - -// ===== impl DecodeError ===== - -impl std::fmt::Display for DecodeError { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - self.err().fmt(f) - } -} - -impl std::error::Error for DecodeError {} diff --git a/holo-vrrp/src/southbound/rx.rs b/holo-vrrp/src/southbound/rx.rs index 24e4dc78..8c1a217f 100644 --- a/holo-vrrp/src/southbound/rx.rs +++ b/holo-vrrp/src/southbound/rx.rs @@ -13,106 +13,81 @@ use ipnetwork::IpNetwork; use crate::interface::Interface; // ===== global functions ===== + pub(crate) fn process_iface_update( - iface: &mut Interface, + interface: &mut Interface, msg: InterfaceUpdateMsg, ) { - // when the iface being updated is the - // main interface for this `holo-vrrp` - if msg.ifname == iface.name { - iface.system.flags = msg.flags; - iface.system.ifindex = Some(msg.ifindex); - iface.system.mac_address = msg.mac_address; - - // update names for all macvlans - for (vrid, instance) in iface.instances.iter_mut() { - instance.mac_vlan.name = format!("mvlan-vrrp-{}", vrid); + let (interface, mut instances) = interface.iter_instances(); + + // Handle updates for the primary VRRP interface. + if msg.ifname == interface.name { + interface.system.flags = msg.flags; + interface.system.ifindex = Some(msg.ifindex); + interface.system.mac_address = msg.mac_address; + for instance in instances { + instance.update(&interface); } return; } - let mut target_vrid: Option = None; - - //check if it is one of the macvlans being updated. - 'outer: for (vrid, instance) in iface.instances.iter_mut() { - let name = msg.ifname.clone(); - let mvlan_iface = &mut instance.mac_vlan; - - if mvlan_iface.name == name { - mvlan_iface.system.flags = msg.flags; - mvlan_iface.system.ifindex = Some(msg.ifindex); - mvlan_iface.system.mac_address = msg.mac_address; - - target_vrid = Some(*vrid); - - break 'outer; - } - } - - if let Some(vrid) = target_vrid { - iface.net_reload(Some(vrid)); + // Handle updates for VRRP macvlan interfaces. + if let Some(instance) = + instances.find(|instance| msg.ifname == instance.mvlan.name) + { + instance.mvlan.system.flags = msg.flags; + instance.mvlan.system.ifindex = Some(msg.ifindex); + instance.mvlan.system.mac_address = msg.mac_address; + instance.update(&interface); } } -pub(crate) fn process_addr_del(iface: &mut Interface, msg: AddressMsg) { - if msg.ifname == iface.name { - // remove the address from the addresses of parent interfaces - if let IpNetwork::V4(addr) = msg.addr { - iface.system.addresses.remove(&addr); - iface.net_reload(None); - } - } - - let mut target_vrid: Option = None; - - 'outer: for (vrid, instance) in iface.instances.iter_mut() { - let name = format!("mvlan-vrrp-{}", vrid); - let mvlan_iface = &mut instance.mac_vlan; +pub(crate) fn process_addr_add(interface: &mut Interface, msg: AddressMsg) { + let (interface, mut instances) = interface.iter_instances(); - // if it is one of the macvlans being edited, we - // remove the macvlan's - if mvlan_iface.name == name { - if let IpNetwork::V4(addr) = msg.addr { - mvlan_iface.system.addresses.remove(&addr); - target_vrid = Some(*vrid); - break 'outer; + // Handle address updates for the primary VRRP interface. + if msg.ifname == interface.name { + if let IpNetwork::V4(addr) = msg.addr { + interface.system.addresses.insert(addr); + for instance in instances { + instance.update(&interface); } } + return; } - if let Some(vrid) = target_vrid { - iface.net_reload(Some(vrid)); - } -} - -pub(crate) fn process_addr_add(iface: &mut Interface, msg: AddressMsg) { - if msg.ifname == iface.name { + // Handle address updates for VRRP macvlan interfaces. + if let Some(instance) = + instances.find(|instance| msg.ifname == instance.mvlan.name) + { if let IpNetwork::V4(addr) = msg.addr { - iface.system.addresses.insert(addr); - iface.net_reload(None); + instance.mvlan.system.addresses.insert(addr); + instance.update(&interface); } } +} - // when this is some, it means that we need to rebind our - // transmission socket multicast address to the newly added address - let mut target_vrid: Option = None; +pub(crate) fn process_addr_del(interface: &mut Interface, msg: AddressMsg) { + let (interface, mut instances) = interface.iter_instances(); - // if the interface being updated is one of the macvlans - 'outer: for (vrid, instance) in iface.instances.iter_mut() { - let name = format!("mvlan-vrrp-{}", vrid); - let mvlan_iface = &mut instance.mac_vlan; - if mvlan_iface.name == name { - if let IpNetwork::V4(addr) = msg.addr { - mvlan_iface.system.addresses.insert(addr); - target_vrid = Some(*vrid); - break 'outer; + // Handle address updates for the primary VRRP interface. + if msg.ifname == interface.name { + if let IpNetwork::V4(addr) = msg.addr { + interface.system.addresses.remove(&addr); + for instance in instances { + instance.update(&interface); } } + return; } - // if the address added was for an instance's macvlan interface - // we reload that sole instance's network configs. - if let Some(vrid) = target_vrid { - iface.net_reload(Some(vrid)); + // Handle address updates for VRRP macvlan interfaces. + if let Some(instance) = + instances.find(|instance| msg.ifname == instance.mvlan.name) + { + if let IpNetwork::V4(addr) = msg.addr { + instance.mvlan.system.addresses.remove(&addr); + instance.update(&interface); + } } } diff --git a/holo-vrrp/src/southbound/tx.rs b/holo-vrrp/src/southbound/tx.rs index 01ad0390..2531f995 100644 --- a/holo-vrrp/src/southbound/tx.rs +++ b/holo-vrrp/src/southbound/tx.rs @@ -9,36 +9,48 @@ use holo_utils::ibus::{IbusMsg, IbusSender}; use holo_utils::southbound::{ - InterfaceIpAddRequestMsg, InterfaceIpDeleteRequestMsg, MacvlanCreateMsg, + InterfaceIpAddRequestMsg, InterfaceIpDelRequestMsg, MacvlanAddMsg, }; use ipnetwork::IpNetwork; -pub(crate) fn create_macvlan_iface( - name: String, +pub(crate) fn mvlan_create( + ibus_tx: &IbusSender, parent_name: String, + name: String, mac_address: [u8; 6], - ibus_tx: &IbusSender, ) { - let msg = MacvlanCreateMsg { + let msg = MacvlanAddMsg { parent_name, name, mac_address: Some(mac_address), }; - let _ = ibus_tx.send(IbusMsg::CreateMacVlan(msg)); + let _ = ibus_tx.send(IbusMsg::MacvlanAdd(msg)); } -pub(crate) fn mvlan_delete(ifindex: u32, ibus_tx: &IbusSender) { - let _ = ibus_tx.send(IbusMsg::InterfaceDeleteRequest(ifindex)); +pub(crate) fn mvlan_delete(ibus_tx: &IbusSender, name: impl Into) { + let _ = ibus_tx.send(IbusMsg::MacvlanDel(name.into())); } -// adds an address to an interface -pub(crate) fn addr_add(ifindex: u32, addr: IpNetwork, ibus_tx: &IbusSender) { - let msg = InterfaceIpAddRequestMsg { ifindex, addr }; +pub(crate) fn ip_addr_add( + ibus_tx: &IbusSender, + ifname: impl Into, + addr: impl Into, +) { + let msg = InterfaceIpAddRequestMsg { + ifname: ifname.into(), + addr: addr.into(), + }; let _ = ibus_tx.send(IbusMsg::InterfaceIpAddRequest(msg)); } -// removes a specific address from an interface -pub(crate) fn addr_del(ifindex: u32, addr: IpNetwork, ibus_tx: &IbusSender) { - let msg = InterfaceIpDeleteRequestMsg { ifindex, addr }; - let _ = ibus_tx.send(IbusMsg::InterfaceIpDeleteRequest(msg)); +pub(crate) fn ip_addr_del( + ibus_tx: &IbusSender, + ifname: impl Into, + addr: impl Into, +) { + let msg = InterfaceIpDelRequestMsg { + ifname: ifname.into(), + addr: addr.into(), + }; + let _ = ibus_tx.send(IbusMsg::InterfaceIpDelRequest(msg)); } diff --git a/holo-vrrp/src/tasks.rs b/holo-vrrp/src/tasks.rs index 2a200af1..3606ffa5 100644 --- a/holo-vrrp/src/tasks.rs +++ b/holo-vrrp/src/tasks.rs @@ -7,19 +7,19 @@ // See: https://nlnet.nl/NGI0 // +use std::net::Ipv4Addr; use std::sync::atomic::Ordering; use std::sync::Arc; use std::time::Duration; use holo_utils::socket::{AsyncFd, Socket}; use holo_utils::task::{IntervalTask, Task, TimeoutTask}; -use holo_utils::{Sender, UnboundedReceiver}; +use holo_utils::{Sender, UnboundedReceiver, UnboundedSender}; use messages::input::MasterDownTimerMsg; use messages::output::NetTxPacketMsg; use tracing::{debug_span, Instrument}; -use crate::instance::{Instance, VrrpTimer}; -use crate::interface::Interface; +use crate::instance::Instance; use crate::network; use crate::packet::VrrpPacket; @@ -32,8 +32,10 @@ use crate::packet::VrrpPacket; // | | // northbound_rx (1x) V | (1x) northbound_tx // +--------------+ -// master_down_timer (Nx) -> | | -// vrrp_net (Nx) -> | instance | -> (Nx) net_tx +// | | +// vrrp_net_rx (Nx) -> | instance | -> (Nx) net_tx +// master_down_timer (Nx) -> | | -> (Nx) advertisement_interval +// | | // +--------------+ // ibus_tx (1x) | ^ (1x) ibus_rx // | | @@ -58,7 +60,6 @@ pub mod messages { use std::net::Ipv4Addr; use super::*; - use crate::packet::ArpHdr; #[derive(Debug, Deserialize, Serialize)] pub enum ProtocolMsg { @@ -72,11 +73,6 @@ pub mod messages { pub packet: Result, } - #[derive(Debug, Deserialize, Serialize)] - pub struct ArpNetRxPacketMsg { - pub packet: Result, - } - #[derive(Debug, Deserialize, Serialize)] pub struct MasterDownTimerMsg { pub vrid: u8, @@ -96,8 +92,7 @@ pub mod messages { #[derive(Clone, Debug, Serialize)] pub enum NetTxPacketMsg { Vrrp { - ifindex: u32, - pkt: VrrpPacket, + packet: VrrpPacket, }, Arp { ifindex: u32, @@ -180,83 +175,60 @@ pub(crate) fn net_tx( } } -// handling the timers... -pub(crate) fn set_timer( - interface: &mut Interface, - vrid: u8, - master_down_tx: Sender, -) { +// Master down timer. +pub(crate) fn master_down_timer( + instance: &mut Instance, + duration: Duration, + master_down_timer_rx: &Sender, +) -> TimeoutTask { #[cfg(not(feature = "testing"))] { - if let Some(instance) = interface.instances.get_mut(&vrid) { - match instance.state.state { - crate::instance::State::Initialize => { - instance.timer = VrrpTimer::Null; - } - crate::instance::State::Backup => { - let duration = Duration::from_secs( - instance.state.master_down_interval as u64, - ); - set_master_down_timer(instance, duration, master_down_tx); - } - - // in case we are Master, we will be sending VRRP advertisements - // every ADVERT_INTERVAL seconds until otherwise. - crate::instance::State::Master => { - if !instance.mac_vlan.is_ready() { - return; - } - let src_ip = - interface.system.addresses.first().unwrap().ip(); - - let ip_hdr = instance.adver_ipv4_pkt(src_ip); - let vrrp_hdr = instance.adver_vrrp_pkt(); + let vrid = instance.vrid; + let master_down_timer_rx = master_down_timer_rx.clone(); - let pkt = VrrpPacket { - ip: ip_hdr, - vrrp: vrrp_hdr, - }; - let ifindex = instance.mac_vlan.system.ifindex.unwrap(); - let adv_sent = instance.state.statistics.adv_sent.clone(); - // ----------------- - if let Some(net) = &instance.mac_vlan.net { - let net_tx = net.net_tx_packetp.clone(); - let timer = IntervalTask::new( - Duration::from_secs( - instance.config.advertise_interval as u64, - ), - true, - move || { - let adv_sent = adv_sent.clone(); - let net_tx = net_tx.clone(); - let pkt = pkt.clone(); - async move { - adv_sent.fetch_add(1, Ordering::Relaxed); - let msg = - NetTxPacketMsg::Vrrp { ifindex, pkt }; - let _ = net_tx.send(msg); - } - }, - ); - instance.timer = VrrpTimer::AdverTimer(timer); - } - } - } - } + TimeoutTask::new(duration, move || async move { + let _ = master_down_timer_rx + .send(messages::input::MasterDownTimerMsg { vrid }) + .await; + }) + } + #[cfg(feature = "testing")] + { + TimeoutTask {} } } -// ==== Set Master Down Timer ==== -pub(crate) fn set_master_down_timer( - instance: &mut Instance, - duration: Duration, - tx: Sender, -) { + +// Advertisement interval. +pub(crate) fn advertisement_interval( + instance: &Instance, + src_ip: Ipv4Addr, + net_tx_packetp: &UnboundedSender, +) -> IntervalTask { #[cfg(not(feature = "testing"))] { - let vrid = instance.vrid; - let timer = TimeoutTask::new(duration, move || async move { - let _ = tx.send(messages::input::MasterDownTimerMsg { vrid }).await; - }); - instance.timer = VrrpTimer::MasterDownTimer(timer); + let packet = VrrpPacket { + ip: instance.generate_ipv4_packet(src_ip), + vrrp: instance.generate_vrrp_packet(), + }; + let adv_sent = instance.state.statistics.adv_sent.clone(); + let net_tx_packetp = net_tx_packetp.clone(); + IntervalTask::new( + Duration::from_secs(instance.config.advertise_interval as u64), + true, + move || { + let adv_sent = adv_sent.clone(); + let packet = packet.clone(); + let net_tx_packetp = net_tx_packetp.clone(); + async move { + adv_sent.fetch_add(1, Ordering::Relaxed); + let msg = NetTxPacketMsg::Vrrp { packet }; + let _ = net_tx_packetp.send(msg); + } + }, + ) + } + #[cfg(feature = "testing")] + { + IntervalTask {} } } diff --git a/holo-vrrp/tests/packet/mod.rs b/holo-vrrp/tests/packet/mod.rs index 76c434dc..a4943d54 100644 --- a/holo-vrrp/tests/packet/mod.rs +++ b/holo-vrrp/tests/packet/mod.rs @@ -77,9 +77,8 @@ static ETHERNETHDR: LazyLock<(Vec, EthernetHdr)> = LazyLock::new(|| { #[test] fn test_encode_vrrphdr() { let (ref bytes, ref vrrphdr) = *VRRPHDR; - let hdr = vrrphdr.clone(); - let generated_bytes = hdr.encode(); + let generated_bytes = vrrphdr.encode(); let generated_data = generated_bytes.as_ref(); let expected_data: &[u8] = bytes.as_ref(); assert_eq!(generated_data, expected_data); @@ -100,9 +99,8 @@ fn test_decode_vrrphdr() { #[test] fn test_encode_ipv4hdr() { let (ref bytes, ref iphdr) = *IPV4HDR; - let hdr = iphdr.clone(); - let generated_bytes = hdr.encode(); + let generated_bytes = iphdr.encode(); let generated_data = generated_bytes.as_ref(); let expected_data: &[u8] = bytes.as_ref(); assert_eq!(generated_data, expected_data); @@ -122,9 +120,8 @@ fn test_decode_ipv4hdr() { #[test] fn test_encode_ethernethdr() { let (ref bytes, ref ethernethdr) = *ETHERNETHDR; - let hdr = ethernethdr.clone(); - let generated_bytes = hdr.encode(); + let generated_bytes = ethernethdr.encode(); let generated_data = generated_bytes.as_ref(); let expected_data: &[u8] = bytes.as_ref(); assert_eq!(generated_data, expected_data); diff --git a/out b/out deleted file mode 100644 index 32562690..00000000 --- a/out +++ /dev/null @@ -1,535 +0,0 @@ ---- -Instance( - 30, - Instance { - vrid: 30, - config: InstanceCfg { - log_state_change: false, - preempt: true, - priority: 100, - advertise_interval: 1, - virtual_addresses: { - Ipv4Network { - addr: 10.0.30.1, - prefix: 32, - }, - Ipv4Network { - addr: 10.0.30.2, - prefix: 32, - }, - }, - }, - state: InstanceState { - state: Master, - last_adv_src: None, - up_time: None, - last_event: MasterTimeout, - new_master_reason: NoResponse, - skew_time: 0.609375, - master_down_interval: 3, - is_owner: false, - statistics: Statistics { - discontinuity_time: 2024-11-13T10:17:40.074684601Z, - master_transitions: 1, - adv_rcvd: 0, - adv_sent: 5, - interval_errors: 0, - priority_zero_pkts_rcvd: 0, - priority_zero_pkts_sent: 0, - invalid_type_pkts_rcvd: 0, - pkt_length_errors: 0, - checksum_errors: 0, - version_errors: 0, - vrid_errors: 0, - ip_ttl_errors: 0, - }, - }, - timer: AdverTimer( - IntervalTask { - inner: IntervalTaskInner { - _task: Task { - join_handle: JoinHandle { - id: Id( - 82, - ), - }, - detached: false, - }, - control: UnboundedSender { - chan: Tx { - inner: Chan { - tx: Tx { - block_tail: 0x000075518001f290, - tail_position: 0, - }, - semaphore: Semaphore( - 0, - ), - rx_waker: AtomicWaker, - tx_count: 1, - rx_fields: "...", - }, - }, - }, - next: Mutex { - data: Instant { - tv_sec: 16100, - tv_nsec: 134915211, - }, - poisoned: false, - .. - }, - }, - }, - ), - mac_vlan: MacVlanInterface { - name: "mvlan-vrrp-30", - system: InterfaceSys { - flags: InterfaceFlags( - OPERATIVE | BROADCAST, - ), - ifindex: Some( - 8, - ), - addresses: { - Ipv4Network { - addr: 10.0.30.1, - prefix: 32, - }, - Ipv4Network { - addr: 10.0.30.2, - prefix: 32, - }, - Ipv4Network { - addr: 10.0.50.1, - prefix: 32, - }, - Ipv4Network { - addr: 10.0.50.2, - prefix: 32, - }, - Ipv4Network { - addr: 10.0.70.1, - prefix: 32, - }, - Ipv4Network { - addr: 10.0.70.2, - prefix: 32, - }, - }, - mac_address: [ - 0, - 0, - 94, - 0, - 1, - 30, - ], - }, - net: Some( - MvlanInterfaceNet { - socket_vrrp: AsyncFd { - inner: Some( - Socket { - raw: 35, - local_addr: Some( - SockAddr { - ss_family: 2, - len: 16, - }, - ), - peer_addr: None, - }, - ), - }, - socket_arp: AsyncFd { - inner: Some( - Socket { - raw: 28, - local_addr: Some( - SockAddr { - ss_family: 17, - len: 12, - }, - ), - peer_addr: None, - }, - ), - }, - _net_tx_task: Task { - join_handle: JoinHandle { - id: Id( - 80, - ), - }, - detached: false, - }, - _vrrp_net_rx_task: Task { - join_handle: JoinHandle { - id: Id( - 81, - ), - }, - detached: false, - }, - net_tx_packetp: UnboundedSender { - chan: Tx { - inner: Chan { - tx: Tx { - block_tail: 0x0000755180025790, - tail_position: 3, - }, - semaphore: Semaphore( - 0, - ), - rx_waker: AtomicWaker, - tx_count: 2, - rx_fields: "...", - }, - }, - }, - }, - ), - }, - }, -) ---- -Instance( - 50, - Instance { - vrid: 50, - config: InstanceCfg { - log_state_change: false, - preempt: true, - priority: 100, - advertise_interval: 1, - virtual_addresses: { - Ipv4Network { - addr: 10.0.50.1, - prefix: 32, - }, - Ipv4Network { - addr: 10.0.50.2, - prefix: 32, - }, - }, - }, - state: InstanceState { - state: Master, - last_adv_src: None, - up_time: None, - last_event: MasterTimeout, - new_master_reason: NoResponse, - skew_time: 0.609375, - master_down_interval: 3, - is_owner: false, - statistics: Statistics { - discontinuity_time: 2024-11-13T10:17:40.074916866Z, - master_transitions: 1, - adv_rcvd: 0, - adv_sent: 3, - interval_errors: 0, - priority_zero_pkts_rcvd: 0, - priority_zero_pkts_sent: 0, - invalid_type_pkts_rcvd: 0, - pkt_length_errors: 0, - checksum_errors: 0, - version_errors: 0, - vrid_errors: 0, - ip_ttl_errors: 0, - }, - }, - timer: AdverTimer( - IntervalTask { - inner: IntervalTaskInner { - _task: Task { - join_handle: JoinHandle { - id: Id( - 63, - ), - }, - detached: false, - }, - control: UnboundedSender { - chan: Tx { - inner: Chan { - tx: Tx { - block_tail: 0x000075518000ba10, - tail_position: 0, - }, - semaphore: Semaphore( - 0, - ), - rx_waker: AtomicWaker, - tx_count: 1, - rx_fields: "...", - }, - }, - }, - next: Mutex { - data: Instant { - tv_sec: 16100, - tv_nsec: 129673689, - }, - poisoned: false, - .. - }, - }, - }, - ), - mac_vlan: MacVlanInterface { - name: "mvlan-vrrp-50", - system: InterfaceSys { - flags: InterfaceFlags( - OPERATIVE | BROADCAST, - ), - ifindex: Some( - 9, - ), - addresses: {}, - mac_address: [ - 0, - 0, - 94, - 0, - 1, - 50, - ], - }, - net: Some( - MvlanInterfaceNet { - socket_vrrp: AsyncFd { - inner: Some( - Socket { - raw: 15, - local_addr: Some( - SockAddr { - ss_family: 2, - len: 16, - }, - ), - peer_addr: None, - }, - ), - }, - socket_arp: AsyncFd { - inner: Some( - Socket { - raw: 21, - local_addr: Some( - SockAddr { - ss_family: 17, - len: 12, - }, - ), - peer_addr: None, - }, - ), - }, - _net_tx_task: Task { - join_handle: JoinHandle { - id: Id( - 53, - ), - }, - detached: false, - }, - _vrrp_net_rx_task: Task { - join_handle: JoinHandle { - id: Id( - 54, - ), - }, - detached: false, - }, - net_tx_packetp: UnboundedSender { - chan: Tx { - inner: Chan { - tx: Tx { - block_tail: 0x0000755180008610, - tail_position: 6, - }, - semaphore: Semaphore( - 0, - ), - rx_waker: AtomicWaker, - tx_count: 2, - rx_fields: "...", - }, - }, - }, - }, - ), - }, - }, -) ---- -Instance( - 70, - Instance { - vrid: 70, - config: InstanceCfg { - log_state_change: false, - preempt: true, - priority: 100, - advertise_interval: 1, - virtual_addresses: { - Ipv4Network { - addr: 10.0.70.1, - prefix: 32, - }, - Ipv4Network { - addr: 10.0.70.2, - prefix: 32, - }, - }, - }, - state: InstanceState { - state: Master, - last_adv_src: None, - up_time: None, - last_event: MasterTimeout, - new_master_reason: NoResponse, - skew_time: 0.609375, - master_down_interval: 3, - is_owner: false, - statistics: Statistics { - discontinuity_time: 2024-11-13T10:17:40.075194026Z, - master_transitions: 1, - adv_rcvd: 0, - adv_sent: 3, - interval_errors: 0, - priority_zero_pkts_rcvd: 0, - priority_zero_pkts_sent: 0, - invalid_type_pkts_rcvd: 0, - pkt_length_errors: 0, - checksum_errors: 0, - version_errors: 0, - vrid_errors: 0, - ip_ttl_errors: 0, - }, - }, - timer: AdverTimer( - IntervalTask { - inner: IntervalTaskInner { - _task: Task { - join_handle: JoinHandle { - id: Id( - 62, - ), - }, - detached: false, - }, - control: UnboundedSender { - chan: Tx { - inner: Chan { - tx: Tx { - block_tail: 0x0000755168027e10, - tail_position: 0, - }, - semaphore: Semaphore( - 0, - ), - rx_waker: AtomicWaker, - tx_count: 1, - rx_fields: "...", - }, - }, - }, - next: Mutex { - data: Instant { - tv_sec: 16100, - tv_nsec: 129578021, - }, - poisoned: false, - .. - }, - }, - }, - ), - mac_vlan: MacVlanInterface { - name: "mvlan-vrrp-70", - system: InterfaceSys { - flags: InterfaceFlags( - OPERATIVE | BROADCAST, - ), - ifindex: Some( - 10, - ), - addresses: {}, - mac_address: [ - 0, - 0, - 94, - 0, - 1, - 70, - ], - }, - net: Some( - MvlanInterfaceNet { - socket_vrrp: AsyncFd { - inner: Some( - Socket { - raw: 22, - local_addr: Some( - SockAddr { - ss_family: 2, - len: 16, - }, - ), - peer_addr: None, - }, - ), - }, - socket_arp: AsyncFd { - inner: Some( - Socket { - raw: 24, - local_addr: Some( - SockAddr { - ss_family: 17, - len: 12, - }, - ), - peer_addr: None, - }, - ), - }, - _net_tx_task: Task { - join_handle: JoinHandle { - id: Id( - 56, - ), - }, - detached: false, - }, - _vrrp_net_rx_task: Task { - join_handle: JoinHandle { - id: Id( - 57, - ), - }, - detached: false, - }, - net_tx_packetp: UnboundedSender { - chan: Tx { - inner: Chan { - tx: Tx { - block_tail: 0x000075518000a590, - tail_position: 6, - }, - semaphore: Semaphore( - 0, - ), - rx_waker: AtomicWaker, - tx_count: 2, - rx_fields: "...", - }, - }, - }, - }, - ), - }, - }, -) diff --git a/run.sh b/run.sh deleted file mode 100755 index 4db6f899..00000000 --- a/run.sh +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/bash - -cargo +nightly build -sudo ./target/debug/holod diff --git a/yng b/yng deleted file mode 100644 index 9fbe7431..00000000 --- a/yng +++ /dev/null @@ -1,1200 +0,0 @@ -YangPath( - "/ietf-interfaces:interfaces/interface", -) -YangPath( - "/ietf-interfaces:interfaces/interface/ietf-ip:ipv4/ietf-vrrp:vrrp/vrrp-instance", -) -YangPath( - "/ietf-interfaces:interfaces/interface/ietf-ip:ipv4/ietf-vrrp:vrrp/vrrp-instance/statistics", -) -YangPath( - "/ietf-key-chain:key-chains/key-chain", -) -YangPath( - "/ietf-key-chain:key-chains/key-chain/key", -) -YangPath( - "/ietf-system:system-state/platform", -) -YangPath( - "/ietf-system:system-state/clock", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol", -) -YangPath( - "/ietf-routing:routing/ribs/rib", -) -YangPath( - "/ietf-routing:routing/ribs/rib/routes/route", -) -YangPath( - "/ietf-routing:routing/ribs/rib/routes/route/next-hop", -) -YangPath( - "/ietf-routing:routing/ribs/rib/routes/route/next-hop/ietf-mpls:mpls-label-stack/entry", -) -YangPath( - "/ietf-routing:routing/ribs/rib/routes/route/next-hop/next-hop-list/next-hop", -) -YangPath( - "/ietf-routing:routing/ribs/rib/routes/route/next-hop/next-hop-list/next-hop/ietf-mpls:mpls-label-stack/entry", -) -YangPath( - "/ietf-routing:routing/holo-routing:birts/birt", -) -YangPath( - "/ietf-routing:routing/holo-routing:birts/birt/bfr-id", -) -YangPath( - "/ietf-routing:routing/holo-routing:birts/birt/bfr-id/birt-entry", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-bfd:bfd/summary", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-bfd:bfd/ietf-bfd-ip-mh:ip-mh/summary", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-bfd:bfd/ietf-bfd-ip-mh:ip-mh/session-groups/session-group", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-bfd:bfd/ietf-bfd-ip-mh:ip-mh/session-groups/session-group/sessions", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-bfd:bfd/ietf-bfd-ip-mh:ip-mh/session-groups/session-group/sessions/session-running", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-bfd:bfd/ietf-bfd-ip-mh:ip-mh/session-groups/session-group/sessions/session-statistics", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-bfd:bfd/ietf-bfd-ip-sh:ip-sh/summary", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-bfd:bfd/ietf-bfd-ip-sh:ip-sh/sessions/session", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-bfd:bfd/ietf-bfd-ip-sh:ip-sh/sessions/session/session-running", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-bfd:bfd/ietf-bfd-ip-sh:ip-sh/sessions/session/session-statistics", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-bgp:bgp/global/afi-safis/afi-safi", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-bgp:bgp/global/afi-safis/afi-safi/statistics", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-bgp:bgp/global/statistics", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-bgp:bgp/neighbors/neighbor", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-bgp:bgp/neighbors/neighbor/timers", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/prefixes", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-bgp:bgp/neighbors/neighbor/capabilities", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-bgp:bgp/neighbors/neighbor/capabilities/advertised-capabilities", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-bgp:bgp/neighbors/neighbor/capabilities/advertised-capabilities/value/mpbgp", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-bgp:bgp/neighbors/neighbor/capabilities/advertised-capabilities/value/asn32", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-bgp:bgp/neighbors/neighbor/capabilities/advertised-capabilities/value/add-paths/afi-safis", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-bgp:bgp/neighbors/neighbor/capabilities/received-capabilities", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-bgp:bgp/neighbors/neighbor/capabilities/received-capabilities/value/mpbgp", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-bgp:bgp/neighbors/neighbor/capabilities/received-capabilities/value/asn32", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-bgp:bgp/neighbors/neighbor/capabilities/received-capabilities/value/add-paths/afi-safis", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-bgp:bgp/neighbors/neighbor/errors/received", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-bgp:bgp/neighbors/neighbor/errors/sent", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-bgp:bgp/neighbors/neighbor/statistics", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-bgp:bgp/neighbors/neighbor/statistics/messages", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-bgp:bgp/rib/attr-sets/attr-set", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-bgp:bgp/rib/attr-sets/attr-set/attributes", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-bgp:bgp/rib/attr-sets/attr-set/attributes/as-path/segment", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-bgp:bgp/rib/attr-sets/attr-set/attributes/as4-path/segment", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-bgp:bgp/rib/attr-sets/attr-set/attributes/aggregator", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-bgp:bgp/rib/attr-sets/attr-set/attributes/aggregator4", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-bgp:bgp/rib/communities/community", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-bgp:bgp/rib/ext-communities/ext-community", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-bgp:bgp/rib/ipv6-ext-communities/ipv6-ext-community", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-bgp:bgp/rib/large-communities/large-community", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-bgp:bgp/rib/afi-safis/afi-safi", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-bgp:bgp/rib/afi-safis/afi-safi/ipv4-unicast/loc-rib/routes/route", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-bgp:bgp/rib/afi-safis/afi-safi/ipv4-unicast/loc-rib/routes/route/unknown-attributes/unknown-attribute", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-bgp:bgp/rib/afi-safis/afi-safi/ipv4-unicast/neighbors/neighbor", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-bgp:bgp/rib/afi-safis/afi-safi/ipv4-unicast/neighbors/neighbor/adj-rib-in-pre/routes/route", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-bgp:bgp/rib/afi-safis/afi-safi/ipv4-unicast/neighbors/neighbor/adj-rib-in-pre/routes/route/unknown-attributes/unknown-attribute", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-bgp:bgp/rib/afi-safis/afi-safi/ipv4-unicast/neighbors/neighbor/adj-rib-in-post/routes/route", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-bgp:bgp/rib/afi-safis/afi-safi/ipv4-unicast/neighbors/neighbor/adj-rib-in-post/routes/route/unknown-attributes/unknown-attribute", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-bgp:bgp/rib/afi-safis/afi-safi/ipv4-unicast/neighbors/neighbor/adj-rib-out-pre/routes/route", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-bgp:bgp/rib/afi-safis/afi-safi/ipv4-unicast/neighbors/neighbor/adj-rib-out-pre/routes/route/unknown-attributes/unknown-attribute", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-bgp:bgp/rib/afi-safis/afi-safi/ipv4-unicast/neighbors/neighbor/adj-rib-out-post/routes/route", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-bgp:bgp/rib/afi-safis/afi-safi/ipv4-unicast/neighbors/neighbor/adj-rib-out-post/routes/route/unknown-attributes/unknown-attribute", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-bgp:bgp/rib/afi-safis/afi-safi/ipv6-unicast/loc-rib/routes/route", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-bgp:bgp/rib/afi-safis/afi-safi/ipv6-unicast/loc-rib/routes/route/unknown-attributes/unknown-attribute", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-bgp:bgp/rib/afi-safis/afi-safi/ipv6-unicast/neighbors/neighbor", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-bgp:bgp/rib/afi-safis/afi-safi/ipv6-unicast/neighbors/neighbor/adj-rib-in-pre/routes/route", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-bgp:bgp/rib/afi-safis/afi-safi/ipv6-unicast/neighbors/neighbor/adj-rib-in-pre/routes/route/unknown-attributes/unknown-attribute", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-bgp:bgp/rib/afi-safis/afi-safi/ipv6-unicast/neighbors/neighbor/adj-rib-in-post/routes/route", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-bgp:bgp/rib/afi-safis/afi-safi/ipv6-unicast/neighbors/neighbor/adj-rib-in-post/routes/route/unknown-attributes/unknown-attribute", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-bgp:bgp/rib/afi-safis/afi-safi/ipv6-unicast/neighbors/neighbor/adj-rib-out-pre/routes/route", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-bgp:bgp/rib/afi-safis/afi-safi/ipv6-unicast/neighbors/neighbor/adj-rib-out-pre/routes/route/unknown-attributes/unknown-attribute", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-bgp:bgp/rib/afi-safis/afi-safi/ipv6-unicast/neighbors/neighbor/adj-rib-out-post/routes/route", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-bgp:bgp/rib/afi-safis/afi-safi/ipv6-unicast/neighbors/neighbor/adj-rib-out-post/routes/route/unknown-attributes/unknown-attribute", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-isis:isis", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-isis:isis/spf-control/ietf-spf-delay", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-isis:isis/spf-log/event", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-isis:isis/spf-log/event/trigger-lsp", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-isis:isis/lsp-log/event", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-isis:isis/lsp-log/event/lsp", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-isis:isis/hostnames/hostname", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-isis:isis/database/levels", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-isis:isis/database/levels/lsp", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-isis:isis/database/levels/lsp/attributes", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-isis:isis/database/levels/lsp/authentication", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-isis:isis/database/levels/lsp/unknown-tlvs/unknown-tlv", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-isis:isis/database/levels/lsp/is-neighbor/neighbor", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-isis:isis/database/levels/lsp/is-neighbor/neighbor/instances/instance", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-isis:isis/database/levels/lsp/is-neighbor/neighbor/instances/instance/default-metric", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-isis:isis/database/levels/lsp/is-neighbor/neighbor/instances/instance/delay-metric", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-isis:isis/database/levels/lsp/is-neighbor/neighbor/instances/instance/expense-metric", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-isis:isis/database/levels/lsp/is-neighbor/neighbor/instances/instance/error-metric", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-isis:isis/database/levels/lsp/extended-is-neighbor/neighbor", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-isis:isis/database/levels/lsp/extended-is-neighbor/neighbor/instances/instance", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-isis:isis/database/levels/lsp/extended-is-neighbor/neighbor/instances/instance/local-if-ipv4-addrs", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-isis:isis/database/levels/lsp/extended-is-neighbor/neighbor/instances/instance/remote-if-ipv4-addrs", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-isis:isis/database/levels/lsp/extended-is-neighbor/neighbor/instances/instance/unreserved-bandwidths/unreserved-bandwidth", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-isis:isis/database/levels/lsp/extended-is-neighbor/neighbor/instances/instance/unknown-tlvs/unknown-tlv", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-isis:isis/database/levels/lsp/ipv4-internal-reachability/prefixes", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-isis:isis/database/levels/lsp/ipv4-internal-reachability/prefixes/default-metric", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-isis:isis/database/levels/lsp/ipv4-internal-reachability/prefixes/delay-metric", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-isis:isis/database/levels/lsp/ipv4-internal-reachability/prefixes/expense-metric", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-isis:isis/database/levels/lsp/ipv4-internal-reachability/prefixes/error-metric", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-isis:isis/database/levels/lsp/ipv4-external-reachability/prefixes", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-isis:isis/database/levels/lsp/ipv4-external-reachability/prefixes/default-metric", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-isis:isis/database/levels/lsp/ipv4-external-reachability/prefixes/delay-metric", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-isis:isis/database/levels/lsp/ipv4-external-reachability/prefixes/expense-metric", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-isis:isis/database/levels/lsp/ipv4-external-reachability/prefixes/error-metric", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-isis:isis/database/levels/lsp/extended-ipv4-reachability/prefixes", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-isis:isis/database/levels/lsp/extended-ipv4-reachability/prefixes/unknown-tlvs/unknown-tlv", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-isis:isis/database/levels/lsp/ipv6-reachability/prefixes", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-isis:isis/database/levels/lsp/ipv6-reachability/prefixes/unknown-tlvs/unknown-tlv", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-isis:isis/local-rib/route", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-isis:isis/local-rib/route/next-hops/next-hop", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-isis:isis/system-counters/level", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-isis:isis/interfaces/interface", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-isis:isis/interfaces/interface/adjacencies/adjacency", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-isis:isis/interfaces/interface/event-counters", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-isis:isis/interfaces/interface/packet-counters/level", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-isis:isis/interfaces/interface/packet-counters/level/iih", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-isis:isis/interfaces/interface/packet-counters/level/lsp", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-isis:isis/interfaces/interface/packet-counters/level/psnp", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-isis:isis/interfaces/interface/packet-counters/level/csnp", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-isis:isis/interfaces/interface/packet-counters/level/unknown", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-mpls-ldp:mpls-ldp/global/address-families/ipv4", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-mpls-ldp:mpls-ldp/global/address-families/ipv4/bindings/address", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-mpls-ldp:mpls-ldp/global/address-families/ipv4/bindings/address/peer", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-mpls-ldp:mpls-ldp/global/address-families/ipv4/bindings/fec-label", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-mpls-ldp:mpls-ldp/global/address-families/ipv4/bindings/fec-label/peer", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-mpls-ldp:mpls-ldp/discovery/interfaces/interface", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-mpls-ldp:mpls-ldp/discovery/interfaces/interface/address-families/ipv4/hello-adjacencies/hello-adjacency", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-mpls-ldp:mpls-ldp/discovery/interfaces/interface/address-families/ipv4/hello-adjacencies/hello-adjacency/hello-holdtime", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-mpls-ldp:mpls-ldp/discovery/interfaces/interface/address-families/ipv4/hello-adjacencies/hello-adjacency/statistics", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-mpls-ldp:mpls-ldp/discovery/interfaces/interface/address-families/ipv4/hello-adjacencies/hello-adjacency/peer", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-mpls-ldp:mpls-ldp/discovery/targeted/address-families/ipv4/hello-adjacencies/hello-adjacency", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-mpls-ldp:mpls-ldp/discovery/targeted/address-families/ipv4/hello-adjacencies/hello-adjacency/hello-holdtime", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-mpls-ldp:mpls-ldp/discovery/targeted/address-families/ipv4/hello-adjacencies/hello-adjacency/statistics", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-mpls-ldp:mpls-ldp/discovery/targeted/address-families/ipv4/hello-adjacencies/hello-adjacency/peer", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-mpls-ldp:mpls-ldp/peers/peer", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-mpls-ldp:mpls-ldp/peers/peer/address-families/ipv4/hello-adjacencies/hello-adjacency", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-mpls-ldp:mpls-ldp/peers/peer/address-families/ipv4/hello-adjacencies/hello-adjacency/hello-holdtime", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-mpls-ldp:mpls-ldp/peers/peer/address-families/ipv4/hello-adjacencies/hello-adjacency/statistics", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-mpls-ldp:mpls-ldp/peers/peer/label-advertisement-mode", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-mpls-ldp:mpls-ldp/peers/peer/received-peer-state/capability/end-of-lib", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-mpls-ldp:mpls-ldp/peers/peer/received-peer-state/capability/typed-wildcard-fec", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-mpls-ldp:mpls-ldp/peers/peer/session-holdtime", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-mpls-ldp:mpls-ldp/peers/peer/tcp-connection", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-mpls-ldp:mpls-ldp/peers/peer/statistics", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-mpls-ldp:mpls-ldp/peers/peer/statistics/received", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-mpls-ldp:mpls-ldp/peers/peer/statistics/sent", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/spf-control/ietf-spf-delay", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/local-rib/route", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/local-rib/route/next-hops/next-hop", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/statistics", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/statistics/database/as-scope-lsa-type", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/database/as-scope-lsa-type", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/database/as-scope-lsa-type/as-scope-lsas/as-scope-lsa", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/spf-log/event", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/spf-log/event/trigger-lsa", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/lsa-log/event", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/lsa-log/event/lsa", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/areas/area", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/areas/area/statistics", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/areas/area/statistics/database/area-scope-lsa-type", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/areas/area/database/area-scope-lsa-type", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/areas/area/database/area-scope-lsa-type/area-scope-lsas/area-scope-lsa", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/areas/area/interfaces/interface", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/areas/area/interfaces/interface/statistics", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/areas/area/interfaces/interface/statistics/database/link-scope-lsa-type", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/areas/area/interfaces/interface/neighbors/neighbor", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/areas/area/interfaces/interface/neighbors/neighbor/statistics", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/areas/area/interfaces/interface/neighbors/neighbor/holo-ospf:graceful-restart", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/areas/area/interfaces/interface/database/link-scope-lsa-type", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/areas/area/interfaces/interface/database/link-scope-lsa-type/link-scope-lsas/link-scope-lsa", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/database/as-scope-lsa-type/as-scope-lsas/as-scope-lsa/ospfv2/header", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/database/as-scope-lsa-type/as-scope-lsas/as-scope-lsa/ospfv2/header/lsa-options", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/database/as-scope-lsa-type/as-scope-lsas/as-scope-lsa/ospfv2/body/external", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/database/as-scope-lsa-type/as-scope-lsas/as-scope-lsa/ospfv2/body/external/topologies/topology", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/database/as-scope-lsa-type/as-scope-lsas/as-scope-lsa/ospfv2/body/opaque/ri-opaque/router-capabilities-tlv/router-informational-capabilities", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/database/as-scope-lsa-type/as-scope-lsas/as-scope-lsa/ospfv2/body/opaque/ri-opaque/router-capabilities-tlv/informational-capabilities-flags", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/database/as-scope-lsa-type/as-scope-lsas/as-scope-lsa/ospfv2/body/opaque/ri-opaque/router-capabilities-tlv/functional-capabilities", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/database/as-scope-lsa-type/as-scope-lsas/as-scope-lsa/ospfv2/body/opaque/ri-opaque/maximum-sid-depth-tlv/msd-type", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/database/as-scope-lsa-type/as-scope-lsas/as-scope-lsa/ospfv2/body/opaque/ri-opaque/unknown-tlvs/unknown-tlv", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/database/as-scope-lsa-type/as-scope-lsas/as-scope-lsa/ospfv2/body/opaque/ri-opaque/ietf-ospf-sr-mpls:sr-algorithm-tlv", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/database/as-scope-lsa-type/as-scope-lsas/as-scope-lsa/ospfv2/body/opaque/ri-opaque/ietf-ospf-sr-mpls:sid-range-tlvs/sid-range-tlv", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/database/as-scope-lsa-type/as-scope-lsas/as-scope-lsa/ospfv2/body/opaque/ri-opaque/ietf-ospf-sr-mpls:sid-range-tlvs/sid-range-tlv/sid-sub-tlv", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/database/as-scope-lsa-type/as-scope-lsas/as-scope-lsa/ospfv2/body/opaque/ri-opaque/ietf-ospf-sr-mpls:local-block-tlvs/local-block-tlv", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/database/as-scope-lsa-type/as-scope-lsas/as-scope-lsa/ospfv2/body/opaque/ri-opaque/ietf-ospf-sr-mpls:local-block-tlvs/local-block-tlv/sid-sub-tlv", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/database/as-scope-lsa-type/as-scope-lsas/as-scope-lsa/ospfv2/body/opaque/ri-opaque/ietf-ospf-sr-mpls:srms-preference-tlv", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/database/as-scope-lsa-type/as-scope-lsas/as-scope-lsa/ospfv2/body/opaque/extended-prefix-opaque/extended-prefix-tlv", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/database/as-scope-lsa-type/as-scope-lsas/as-scope-lsa/ospfv2/body/opaque/extended-prefix-opaque/extended-prefix-tlv/flags", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/database/as-scope-lsa-type/as-scope-lsas/as-scope-lsa/ospfv2/body/opaque/extended-prefix-opaque/extended-prefix-tlv/unknown-tlvs/unknown-tlv", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/database/as-scope-lsa-type/as-scope-lsas/as-scope-lsa/ospfv2/body/opaque/extended-prefix-opaque/extended-prefix-tlv/ietf-ospf-sr-mpls:prefix-sid-sub-tlvs/prefix-sid-sub-tlv", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/database/as-scope-lsa-type/as-scope-lsas/as-scope-lsa/ospfv2/body/opaque/extended-prefix-opaque/extended-prefix-tlv/ietf-ospf-sr-mpls:prefix-sid-sub-tlvs/prefix-sid-sub-tlv/prefix-sid-flags", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/areas/area/database/area-scope-lsa-type/area-scope-lsas/area-scope-lsa/ospfv2/header", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/areas/area/database/area-scope-lsa-type/area-scope-lsas/area-scope-lsa/ospfv2/header/lsa-options", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/areas/area/database/area-scope-lsa-type/area-scope-lsas/area-scope-lsa/ospfv2/body/router", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/areas/area/database/area-scope-lsa-type/area-scope-lsas/area-scope-lsa/ospfv2/body/router/router-bits", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/areas/area/database/area-scope-lsa-type/area-scope-lsas/area-scope-lsa/ospfv2/body/router/links/link", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/areas/area/database/area-scope-lsa-type/area-scope-lsas/area-scope-lsa/ospfv2/body/router/links/link/topologies/topology", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/areas/area/database/area-scope-lsa-type/area-scope-lsas/area-scope-lsa/ospfv2/body/network", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/areas/area/database/area-scope-lsa-type/area-scope-lsas/area-scope-lsa/ospfv2/body/network/attached-routers", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/areas/area/database/area-scope-lsa-type/area-scope-lsas/area-scope-lsa/ospfv2/body/summary", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/areas/area/database/area-scope-lsa-type/area-scope-lsas/area-scope-lsa/ospfv2/body/summary/topologies/topology", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/areas/area/database/area-scope-lsa-type/area-scope-lsas/area-scope-lsa/ospfv2/body/opaque/ri-opaque/router-capabilities-tlv/router-informational-capabilities", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/areas/area/database/area-scope-lsa-type/area-scope-lsas/area-scope-lsa/ospfv2/body/opaque/ri-opaque/router-capabilities-tlv/informational-capabilities-flags", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/areas/area/database/area-scope-lsa-type/area-scope-lsas/area-scope-lsa/ospfv2/body/opaque/ri-opaque/router-capabilities-tlv/functional-capabilities", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/areas/area/database/area-scope-lsa-type/area-scope-lsas/area-scope-lsa/ospfv2/body/opaque/ri-opaque/maximum-sid-depth-tlv/msd-type", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/areas/area/database/area-scope-lsa-type/area-scope-lsas/area-scope-lsa/ospfv2/body/opaque/ri-opaque/unknown-tlvs/unknown-tlv", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/areas/area/database/area-scope-lsa-type/area-scope-lsas/area-scope-lsa/ospfv2/body/opaque/ri-opaque/ietf-ospf-sr-mpls:sr-algorithm-tlv", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/areas/area/database/area-scope-lsa-type/area-scope-lsas/area-scope-lsa/ospfv2/body/opaque/ri-opaque/ietf-ospf-sr-mpls:sid-range-tlvs/sid-range-tlv", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/areas/area/database/area-scope-lsa-type/area-scope-lsas/area-scope-lsa/ospfv2/body/opaque/ri-opaque/ietf-ospf-sr-mpls:sid-range-tlvs/sid-range-tlv/sid-sub-tlv", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/areas/area/database/area-scope-lsa-type/area-scope-lsas/area-scope-lsa/ospfv2/body/opaque/ri-opaque/ietf-ospf-sr-mpls:local-block-tlvs/local-block-tlv", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/areas/area/database/area-scope-lsa-type/area-scope-lsas/area-scope-lsa/ospfv2/body/opaque/ri-opaque/ietf-ospf-sr-mpls:local-block-tlvs/local-block-tlv/sid-sub-tlv", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/areas/area/database/area-scope-lsa-type/area-scope-lsas/area-scope-lsa/ospfv2/body/opaque/ri-opaque/ietf-ospf-sr-mpls:srms-preference-tlv", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/areas/area/database/area-scope-lsa-type/area-scope-lsas/area-scope-lsa/ospfv2/body/opaque/extended-prefix-opaque/extended-prefix-tlv", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/areas/area/database/area-scope-lsa-type/area-scope-lsas/area-scope-lsa/ospfv2/body/opaque/extended-prefix-opaque/extended-prefix-tlv/flags", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/areas/area/database/area-scope-lsa-type/area-scope-lsas/area-scope-lsa/ospfv2/body/opaque/extended-prefix-opaque/extended-prefix-tlv/unknown-tlvs/unknown-tlv", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/areas/area/database/area-scope-lsa-type/area-scope-lsas/area-scope-lsa/ospfv2/body/opaque/extended-prefix-opaque/extended-prefix-tlv/ietf-ospf-sr-mpls:prefix-sid-sub-tlvs/prefix-sid-sub-tlv", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/areas/area/database/area-scope-lsa-type/area-scope-lsas/area-scope-lsa/ospfv2/body/opaque/extended-prefix-opaque/extended-prefix-tlv/ietf-ospf-sr-mpls:prefix-sid-sub-tlvs/prefix-sid-sub-tlv/prefix-sid-flags", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/areas/area/database/area-scope-lsa-type/area-scope-lsas/area-scope-lsa/ospfv2/body/opaque/extended-link-opaque/extended-link-tlv", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/areas/area/database/area-scope-lsa-type/area-scope-lsas/area-scope-lsa/ospfv2/body/opaque/extended-link-opaque/extended-link-tlv/maximum-sid-depth-tlv/msd-type", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/areas/area/database/area-scope-lsa-type/area-scope-lsas/area-scope-lsa/ospfv2/body/opaque/extended-link-opaque/extended-link-tlv/unknown-tlvs/unknown-tlv", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/areas/area/database/area-scope-lsa-type/area-scope-lsas/area-scope-lsa/ospfv2/body/opaque/extended-link-opaque/extended-link-tlv/ietf-ospf-sr-mpls:adj-sid-sub-tlvs/adj-sid-sub-tlv", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/areas/area/database/area-scope-lsa-type/area-scope-lsas/area-scope-lsa/ospfv2/body/opaque/extended-link-opaque/extended-link-tlv/ietf-ospf-sr-mpls:adj-sid-sub-tlvs/adj-sid-sub-tlv/adj-sid-flags", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/areas/area/database/area-scope-lsa-type/area-scope-lsas/area-scope-lsa/ospfv2/body/opaque/extended-link-opaque/extended-link-tlv/ietf-ospf-sr-mpls:lan-adj-sid-sub-tlvs/lan-adj-sid-sub-tlv", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/areas/area/database/area-scope-lsa-type/area-scope-lsas/area-scope-lsa/ospfv2/body/opaque/extended-link-opaque/extended-link-tlv/ietf-ospf-sr-mpls:lan-adj-sid-sub-tlvs/lan-adj-sid-sub-tlv/lan-adj-sid-flags", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/areas/area/interfaces/interface/database/link-scope-lsa-type/link-scope-lsas/link-scope-lsa/ospfv2/header", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/areas/area/interfaces/interface/database/link-scope-lsa-type/link-scope-lsas/link-scope-lsa/ospfv2/header/lsa-options", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/areas/area/interfaces/interface/database/link-scope-lsa-type/link-scope-lsas/link-scope-lsa/ospfv2/body/opaque/ri-opaque/router-capabilities-tlv/router-informational-capabilities", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/areas/area/interfaces/interface/database/link-scope-lsa-type/link-scope-lsas/link-scope-lsa/ospfv2/body/opaque/ri-opaque/router-capabilities-tlv/informational-capabilities-flags", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/areas/area/interfaces/interface/database/link-scope-lsa-type/link-scope-lsas/link-scope-lsa/ospfv2/body/opaque/ri-opaque/router-capabilities-tlv/functional-capabilities", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/areas/area/interfaces/interface/database/link-scope-lsa-type/link-scope-lsas/link-scope-lsa/ospfv2/body/opaque/ri-opaque/maximum-sid-depth-tlv/msd-type", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/areas/area/interfaces/interface/database/link-scope-lsa-type/link-scope-lsas/link-scope-lsa/ospfv2/body/opaque/ri-opaque/unknown-tlvs/unknown-tlv", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/areas/area/interfaces/interface/database/link-scope-lsa-type/link-scope-lsas/link-scope-lsa/ospfv2/body/opaque/ri-opaque/ietf-ospf-sr-mpls:sr-algorithm-tlv", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/areas/area/interfaces/interface/database/link-scope-lsa-type/link-scope-lsas/link-scope-lsa/ospfv2/body/opaque/ri-opaque/ietf-ospf-sr-mpls:sid-range-tlvs/sid-range-tlv", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/areas/area/interfaces/interface/database/link-scope-lsa-type/link-scope-lsas/link-scope-lsa/ospfv2/body/opaque/ri-opaque/ietf-ospf-sr-mpls:sid-range-tlvs/sid-range-tlv/sid-sub-tlv", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/areas/area/interfaces/interface/database/link-scope-lsa-type/link-scope-lsas/link-scope-lsa/ospfv2/body/opaque/ri-opaque/ietf-ospf-sr-mpls:local-block-tlvs/local-block-tlv", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/areas/area/interfaces/interface/database/link-scope-lsa-type/link-scope-lsas/link-scope-lsa/ospfv2/body/opaque/ri-opaque/ietf-ospf-sr-mpls:local-block-tlvs/local-block-tlv/sid-sub-tlv", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/areas/area/interfaces/interface/database/link-scope-lsa-type/link-scope-lsas/link-scope-lsa/ospfv2/body/opaque/ri-opaque/ietf-ospf-sr-mpls:srms-preference-tlv", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/areas/area/interfaces/interface/database/link-scope-lsa-type/link-scope-lsas/link-scope-lsa/ospfv2/body/opaque/holo-ospf:grace", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/spf-control/ietf-spf-delay", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/local-rib/route", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/local-rib/route/next-hops/next-hop", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/statistics", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/statistics/database/as-scope-lsa-type", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/database/as-scope-lsa-type", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/database/as-scope-lsa-type/as-scope-lsas/as-scope-lsa", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/spf-log/event", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/spf-log/event/trigger-lsa", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/lsa-log/event", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/lsa-log/event/lsa", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/areas/area", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/areas/area/statistics", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/areas/area/statistics/database/area-scope-lsa-type", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/areas/area/database/area-scope-lsa-type", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/areas/area/database/area-scope-lsa-type/area-scope-lsas/area-scope-lsa", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/areas/area/interfaces/interface", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/areas/area/interfaces/interface/statistics", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/areas/area/interfaces/interface/statistics/database/link-scope-lsa-type", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/areas/area/interfaces/interface/neighbors/neighbor", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/areas/area/interfaces/interface/neighbors/neighbor/statistics", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/areas/area/interfaces/interface/neighbors/neighbor/holo-ospf:graceful-restart", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/areas/area/interfaces/interface/database/link-scope-lsa-type", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/areas/area/interfaces/interface/database/link-scope-lsa-type/link-scope-lsas/link-scope-lsa", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/database/as-scope-lsa-type/as-scope-lsas/as-scope-lsa/ospfv3/header", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/database/as-scope-lsa-type/as-scope-lsas/as-scope-lsa/ospfv3/body/as-external", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/database/as-scope-lsa-type/as-scope-lsas/as-scope-lsa/ospfv3/body/as-external/prefix-options", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/database/as-scope-lsa-type/as-scope-lsas/as-scope-lsa/ospfv3/body/router-information/router-capabilities-tlv/router-informational-capabilities", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/database/as-scope-lsa-type/as-scope-lsas/as-scope-lsa/ospfv3/body/router-information/router-capabilities-tlv/informational-capabilities-flags", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/database/as-scope-lsa-type/as-scope-lsas/as-scope-lsa/ospfv3/body/router-information/router-capabilities-tlv/functional-capabilities", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/database/as-scope-lsa-type/as-scope-lsas/as-scope-lsa/ospfv3/body/router-information/ietf-ospf-sr-mpls:sr-algorithm-tlv", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/database/as-scope-lsa-type/as-scope-lsas/as-scope-lsa/ospfv3/body/router-information/ietf-ospf-sr-mpls:sid-range-tlvs/sid-range-tlv", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/database/as-scope-lsa-type/as-scope-lsas/as-scope-lsa/ospfv3/body/router-information/ietf-ospf-sr-mpls:sid-range-tlvs/sid-range-tlv/sid-sub-tlv", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/database/as-scope-lsa-type/as-scope-lsas/as-scope-lsa/ospfv3/body/router-information/ietf-ospf-sr-mpls:local-block-tlvs/local-block-tlv", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/database/as-scope-lsa-type/as-scope-lsas/as-scope-lsa/ospfv3/body/router-information/ietf-ospf-sr-mpls:local-block-tlvs/local-block-tlv/sid-sub-tlv", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/database/as-scope-lsa-type/as-scope-lsas/as-scope-lsa/ospfv3/body/router-information/ietf-ospf-sr-mpls:srms-preference-tlv", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/database/as-scope-lsa-type/as-scope-lsas/as-scope-lsa/ospfv3/body/ietf-ospfv3-extended-lsa:e-as-external/e-external-tlvs", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/database/as-scope-lsa-type/as-scope-lsas/as-scope-lsa/ospfv3/body/ietf-ospfv3-extended-lsa:e-as-external/e-external-tlvs/unknown-tlv", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/database/as-scope-lsa-type/as-scope-lsas/as-scope-lsa/ospfv3/body/ietf-ospfv3-extended-lsa:e-as-external/e-external-tlvs/external-prefix-tlv", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/database/as-scope-lsa-type/as-scope-lsas/as-scope-lsa/ospfv3/body/ietf-ospfv3-extended-lsa:e-as-external/e-external-tlvs/external-prefix-tlv/flags", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/database/as-scope-lsa-type/as-scope-lsas/as-scope-lsa/ospfv3/body/ietf-ospfv3-extended-lsa:e-as-external/e-external-tlvs/external-prefix-tlv/prefix-options", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/database/as-scope-lsa-type/as-scope-lsas/as-scope-lsa/ospfv3/body/ietf-ospfv3-extended-lsa:e-as-external/e-external-tlvs/external-prefix-tlv/sub-tlvs", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/database/as-scope-lsa-type/as-scope-lsas/as-scope-lsa/ospfv3/body/ietf-ospfv3-extended-lsa:e-as-external/e-external-tlvs/external-prefix-tlv/sub-tlvs/ipv6-fwd-addr-sub-tlv", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/database/as-scope-lsa-type/as-scope-lsas/as-scope-lsa/ospfv3/body/ietf-ospfv3-extended-lsa:e-as-external/e-external-tlvs/external-prefix-tlv/sub-tlvs/ipv4-fwd-addr-sub-tlv", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/database/as-scope-lsa-type/as-scope-lsas/as-scope-lsa/ospfv3/body/ietf-ospfv3-extended-lsa:e-as-external/e-external-tlvs/external-prefix-tlv/sub-tlvs/route-tag-sub-tlv", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/database/as-scope-lsa-type/as-scope-lsas/as-scope-lsa/ospfv3/body/ietf-ospfv3-extended-lsa:e-as-external/e-external-tlvs/external-prefix-tlv/sub-tlvs/unknown-sub-tlv", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/database/as-scope-lsa-type/as-scope-lsas/as-scope-lsa/ospfv3/body/ietf-ospfv3-extended-lsa:e-as-external/e-external-tlvs/external-prefix-tlv/sub-tlvs/ietf-ospf-sr-mpls:prefix-sid-sub-tlvs/prefix-sid-sub-tlv", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/database/as-scope-lsa-type/as-scope-lsas/as-scope-lsa/ospfv3/body/ietf-ospfv3-extended-lsa:e-as-external/e-external-tlvs/external-prefix-tlv/sub-tlvs/ietf-ospf-sr-mpls:prefix-sid-sub-tlvs/prefix-sid-sub-tlv/ospfv3-prefix-sid-flags", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/areas/area/database/area-scope-lsa-type/area-scope-lsas/area-scope-lsa/ospfv3/header", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/areas/area/database/area-scope-lsa-type/area-scope-lsas/area-scope-lsa/ospfv3/body/router/router-bits", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/areas/area/database/area-scope-lsa-type/area-scope-lsas/area-scope-lsa/ospfv3/body/router/lsa-options", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/areas/area/database/area-scope-lsa-type/area-scope-lsas/area-scope-lsa/ospfv3/body/router/links/link", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/areas/area/database/area-scope-lsa-type/area-scope-lsas/area-scope-lsa/ospfv3/body/network/lsa-options", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/areas/area/database/area-scope-lsa-type/area-scope-lsas/area-scope-lsa/ospfv3/body/network/attached-routers", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/areas/area/database/area-scope-lsa-type/area-scope-lsas/area-scope-lsa/ospfv3/body/inter-area-prefix", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/areas/area/database/area-scope-lsa-type/area-scope-lsas/area-scope-lsa/ospfv3/body/inter-area-prefix/prefix-options", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/areas/area/database/area-scope-lsa-type/area-scope-lsas/area-scope-lsa/ospfv3/body/inter-area-router", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/areas/area/database/area-scope-lsa-type/area-scope-lsas/area-scope-lsa/ospfv3/body/inter-area-router/lsa-options", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/areas/area/database/area-scope-lsa-type/area-scope-lsas/area-scope-lsa/ospfv3/body/intra-area-prefix", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/areas/area/database/area-scope-lsa-type/area-scope-lsas/area-scope-lsa/ospfv3/body/intra-area-prefix/prefixes/prefix", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/areas/area/database/area-scope-lsa-type/area-scope-lsas/area-scope-lsa/ospfv3/body/intra-area-prefix/prefixes/prefix/prefix-options", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/areas/area/database/area-scope-lsa-type/area-scope-lsas/area-scope-lsa/ospfv3/body/router-information/router-capabilities-tlv/router-informational-capabilities", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/areas/area/database/area-scope-lsa-type/area-scope-lsas/area-scope-lsa/ospfv3/body/router-information/router-capabilities-tlv/informational-capabilities-flags", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/areas/area/database/area-scope-lsa-type/area-scope-lsas/area-scope-lsa/ospfv3/body/router-information/router-capabilities-tlv/functional-capabilities", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/areas/area/database/area-scope-lsa-type/area-scope-lsas/area-scope-lsa/ospfv3/body/router-information/ietf-ospf-sr-mpls:sr-algorithm-tlv", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/areas/area/database/area-scope-lsa-type/area-scope-lsas/area-scope-lsa/ospfv3/body/router-information/ietf-ospf-sr-mpls:sid-range-tlvs/sid-range-tlv", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/areas/area/database/area-scope-lsa-type/area-scope-lsas/area-scope-lsa/ospfv3/body/router-information/ietf-ospf-sr-mpls:sid-range-tlvs/sid-range-tlv/sid-sub-tlv", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/areas/area/database/area-scope-lsa-type/area-scope-lsas/area-scope-lsa/ospfv3/body/router-information/ietf-ospf-sr-mpls:local-block-tlvs/local-block-tlv", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/areas/area/database/area-scope-lsa-type/area-scope-lsas/area-scope-lsa/ospfv3/body/router-information/ietf-ospf-sr-mpls:local-block-tlvs/local-block-tlv/sid-sub-tlv", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/areas/area/database/area-scope-lsa-type/area-scope-lsas/area-scope-lsa/ospfv3/body/router-information/ietf-ospf-sr-mpls:srms-preference-tlv", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/areas/area/database/area-scope-lsa-type/area-scope-lsas/area-scope-lsa/ospfv3/body/ietf-ospfv3-extended-lsa:e-router/router-bits", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/areas/area/database/area-scope-lsa-type/area-scope-lsas/area-scope-lsa/ospfv3/body/ietf-ospfv3-extended-lsa:e-router/lsa-options", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/areas/area/database/area-scope-lsa-type/area-scope-lsas/area-scope-lsa/ospfv3/body/ietf-ospfv3-extended-lsa:e-router/e-router-tlvs", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/areas/area/database/area-scope-lsa-type/area-scope-lsas/area-scope-lsa/ospfv3/body/ietf-ospfv3-extended-lsa:e-router/e-router-tlvs/unknown-tlv", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/areas/area/database/area-scope-lsa-type/area-scope-lsas/area-scope-lsa/ospfv3/body/ietf-ospfv3-extended-lsa:e-router/e-router-tlvs/link-tlv", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/areas/area/database/area-scope-lsa-type/area-scope-lsas/area-scope-lsa/ospfv3/body/ietf-ospfv3-extended-lsa:e-router/e-router-tlvs/link-tlv/sub-tlvs", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/areas/area/database/area-scope-lsa-type/area-scope-lsas/area-scope-lsa/ospfv3/body/ietf-ospfv3-extended-lsa:e-router/e-router-tlvs/link-tlv/sub-tlvs/unknown-sub-tlv", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/areas/area/database/area-scope-lsa-type/area-scope-lsas/area-scope-lsa/ospfv3/body/ietf-ospfv3-extended-lsa:e-router/e-router-tlvs/link-tlv/sub-tlvs/ietf-ospf-sr-mpls:adj-sid-sub-tlvs/adj-sid-sub-tlv", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/areas/area/database/area-scope-lsa-type/area-scope-lsas/area-scope-lsa/ospfv3/body/ietf-ospfv3-extended-lsa:e-router/e-router-tlvs/link-tlv/sub-tlvs/ietf-ospf-sr-mpls:adj-sid-sub-tlvs/adj-sid-sub-tlv/adj-sid-flags", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/areas/area/database/area-scope-lsa-type/area-scope-lsas/area-scope-lsa/ospfv3/body/ietf-ospfv3-extended-lsa:e-router/e-router-tlvs/link-tlv/sub-tlvs/ietf-ospf-sr-mpls:lan-adj-sid-sub-tlvs/lan-adj-sid-sub-tlv", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/areas/area/database/area-scope-lsa-type/area-scope-lsas/area-scope-lsa/ospfv3/body/ietf-ospfv3-extended-lsa:e-router/e-router-tlvs/link-tlv/sub-tlvs/ietf-ospf-sr-mpls:lan-adj-sid-sub-tlvs/lan-adj-sid-sub-tlv/lan-adj-sid-flags", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/areas/area/database/area-scope-lsa-type/area-scope-lsas/area-scope-lsa/ospfv3/body/ietf-ospfv3-extended-lsa:e-network/lsa-options", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/areas/area/database/area-scope-lsa-type/area-scope-lsas/area-scope-lsa/ospfv3/body/ietf-ospfv3-extended-lsa:e-network/e-network-tlvs", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/areas/area/database/area-scope-lsa-type/area-scope-lsas/area-scope-lsa/ospfv3/body/ietf-ospfv3-extended-lsa:e-network/e-network-tlvs/unknown-tlv", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/areas/area/database/area-scope-lsa-type/area-scope-lsas/area-scope-lsa/ospfv3/body/ietf-ospfv3-extended-lsa:e-network/e-network-tlvs/attached-router-tlv", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/areas/area/database/area-scope-lsa-type/area-scope-lsas/area-scope-lsa/ospfv3/body/ietf-ospfv3-extended-lsa:e-inter-area-prefix/e-inter-prefix-tlvs", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/areas/area/database/area-scope-lsa-type/area-scope-lsas/area-scope-lsa/ospfv3/body/ietf-ospfv3-extended-lsa:e-inter-area-prefix/e-inter-prefix-tlvs/unknown-tlv", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/areas/area/database/area-scope-lsa-type/area-scope-lsas/area-scope-lsa/ospfv3/body/ietf-ospfv3-extended-lsa:e-inter-area-prefix/e-inter-prefix-tlvs/inter-prefix-tlv", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/areas/area/database/area-scope-lsa-type/area-scope-lsas/area-scope-lsa/ospfv3/body/ietf-ospfv3-extended-lsa:e-inter-area-prefix/e-inter-prefix-tlvs/inter-prefix-tlv/prefix-options", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/areas/area/database/area-scope-lsa-type/area-scope-lsas/area-scope-lsa/ospfv3/body/ietf-ospfv3-extended-lsa:e-inter-area-prefix/e-inter-prefix-tlvs/inter-prefix-tlv/sub-tlvs", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/areas/area/database/area-scope-lsa-type/area-scope-lsas/area-scope-lsa/ospfv3/body/ietf-ospfv3-extended-lsa:e-inter-area-prefix/e-inter-prefix-tlvs/inter-prefix-tlv/sub-tlvs/unknown-sub-tlv", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/areas/area/database/area-scope-lsa-type/area-scope-lsas/area-scope-lsa/ospfv3/body/ietf-ospfv3-extended-lsa:e-inter-area-prefix/e-inter-prefix-tlvs/inter-prefix-tlv/sub-tlvs/ietf-ospf-sr-mpls:prefix-sid-sub-tlvs/prefix-sid-sub-tlv", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/areas/area/database/area-scope-lsa-type/area-scope-lsas/area-scope-lsa/ospfv3/body/ietf-ospfv3-extended-lsa:e-inter-area-prefix/e-inter-prefix-tlvs/inter-prefix-tlv/sub-tlvs/ietf-ospf-sr-mpls:prefix-sid-sub-tlvs/prefix-sid-sub-tlv/ospfv3-prefix-sid-flags", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/areas/area/database/area-scope-lsa-type/area-scope-lsas/area-scope-lsa/ospfv3/body/ietf-ospfv3-extended-lsa:e-inter-area-router/e-inter-router-tlvs", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/areas/area/database/area-scope-lsa-type/area-scope-lsas/area-scope-lsa/ospfv3/body/ietf-ospfv3-extended-lsa:e-inter-area-router/e-inter-router-tlvs/unknown-tlv", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/areas/area/database/area-scope-lsa-type/area-scope-lsas/area-scope-lsa/ospfv3/body/ietf-ospfv3-extended-lsa:e-inter-area-router/e-inter-router-tlvs/inter-router-tlv", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/areas/area/database/area-scope-lsa-type/area-scope-lsas/area-scope-lsa/ospfv3/body/ietf-ospfv3-extended-lsa:e-inter-area-router/e-inter-router-tlvs/inter-router-tlv/lsa-options", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/areas/area/database/area-scope-lsa-type/area-scope-lsas/area-scope-lsa/ospfv3/body/ietf-ospfv3-extended-lsa:e-inter-area-router/e-inter-router-tlvs/inter-router-tlv/sub-tlvs", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/areas/area/database/area-scope-lsa-type/area-scope-lsas/area-scope-lsa/ospfv3/body/ietf-ospfv3-extended-lsa:e-inter-area-router/e-inter-router-tlvs/inter-router-tlv/sub-tlvs/unknown-sub-tlv", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/areas/area/database/area-scope-lsa-type/area-scope-lsas/area-scope-lsa/ospfv3/body/ietf-ospfv3-extended-lsa:e-intra-area-prefix", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/areas/area/database/area-scope-lsa-type/area-scope-lsas/area-scope-lsa/ospfv3/body/ietf-ospfv3-extended-lsa:e-intra-area-prefix/e-intra-prefix-tlvs", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/areas/area/database/area-scope-lsa-type/area-scope-lsas/area-scope-lsa/ospfv3/body/ietf-ospfv3-extended-lsa:e-intra-area-prefix/e-intra-prefix-tlvs/unknown-tlv", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/areas/area/database/area-scope-lsa-type/area-scope-lsas/area-scope-lsa/ospfv3/body/ietf-ospfv3-extended-lsa:e-intra-area-prefix/e-intra-prefix-tlvs/intra-prefix-tlv", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/areas/area/database/area-scope-lsa-type/area-scope-lsas/area-scope-lsa/ospfv3/body/ietf-ospfv3-extended-lsa:e-intra-area-prefix/e-intra-prefix-tlvs/intra-prefix-tlv/prefix-options", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/areas/area/database/area-scope-lsa-type/area-scope-lsas/area-scope-lsa/ospfv3/body/ietf-ospfv3-extended-lsa:e-intra-area-prefix/e-intra-prefix-tlvs/intra-prefix-tlv/sub-tlvs", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/areas/area/database/area-scope-lsa-type/area-scope-lsas/area-scope-lsa/ospfv3/body/ietf-ospfv3-extended-lsa:e-intra-area-prefix/e-intra-prefix-tlvs/intra-prefix-tlv/sub-tlvs/unknown-sub-tlv", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/areas/area/database/area-scope-lsa-type/area-scope-lsas/area-scope-lsa/ospfv3/body/ietf-ospfv3-extended-lsa:e-intra-area-prefix/e-intra-prefix-tlvs/intra-prefix-tlv/sub-tlvs/ietf-ospf-sr-mpls:prefix-sid-sub-tlvs/prefix-sid-sub-tlv", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/areas/area/database/area-scope-lsa-type/area-scope-lsas/area-scope-lsa/ospfv3/body/ietf-ospfv3-extended-lsa:e-intra-area-prefix/e-intra-prefix-tlvs/intra-prefix-tlv/sub-tlvs/ietf-ospf-sr-mpls:prefix-sid-sub-tlvs/prefix-sid-sub-tlv/ospfv3-prefix-sid-flags", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/areas/area/interfaces/interface/database/link-scope-lsa-type/link-scope-lsas/link-scope-lsa/ospfv3/header", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/areas/area/interfaces/interface/database/link-scope-lsa-type/link-scope-lsas/link-scope-lsa/ospfv3/body/link", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/areas/area/interfaces/interface/database/link-scope-lsa-type/link-scope-lsas/link-scope-lsa/ospfv3/body/link/lsa-options", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/areas/area/interfaces/interface/database/link-scope-lsa-type/link-scope-lsas/link-scope-lsa/ospfv3/body/link/prefixes/prefix", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/areas/area/interfaces/interface/database/link-scope-lsa-type/link-scope-lsas/link-scope-lsa/ospfv3/body/link/prefixes/prefix/prefix-options", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/areas/area/interfaces/interface/database/link-scope-lsa-type/link-scope-lsas/link-scope-lsa/ospfv3/body/router-information/router-capabilities-tlv/router-informational-capabilities", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/areas/area/interfaces/interface/database/link-scope-lsa-type/link-scope-lsas/link-scope-lsa/ospfv3/body/router-information/router-capabilities-tlv/informational-capabilities-flags", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/areas/area/interfaces/interface/database/link-scope-lsa-type/link-scope-lsas/link-scope-lsa/ospfv3/body/router-information/router-capabilities-tlv/functional-capabilities", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/areas/area/interfaces/interface/database/link-scope-lsa-type/link-scope-lsas/link-scope-lsa/ospfv3/body/router-information/ietf-ospf-sr-mpls:sr-algorithm-tlv", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/areas/area/interfaces/interface/database/link-scope-lsa-type/link-scope-lsas/link-scope-lsa/ospfv3/body/router-information/ietf-ospf-sr-mpls:sid-range-tlvs/sid-range-tlv", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/areas/area/interfaces/interface/database/link-scope-lsa-type/link-scope-lsas/link-scope-lsa/ospfv3/body/router-information/ietf-ospf-sr-mpls:sid-range-tlvs/sid-range-tlv/sid-sub-tlv", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/areas/area/interfaces/interface/database/link-scope-lsa-type/link-scope-lsas/link-scope-lsa/ospfv3/body/router-information/ietf-ospf-sr-mpls:local-block-tlvs/local-block-tlv", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/areas/area/interfaces/interface/database/link-scope-lsa-type/link-scope-lsas/link-scope-lsa/ospfv3/body/router-information/ietf-ospf-sr-mpls:local-block-tlvs/local-block-tlv/sid-sub-tlv", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/areas/area/interfaces/interface/database/link-scope-lsa-type/link-scope-lsas/link-scope-lsa/ospfv3/body/router-information/ietf-ospf-sr-mpls:srms-preference-tlv", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/areas/area/interfaces/interface/database/link-scope-lsa-type/link-scope-lsas/link-scope-lsa/ospfv3/body/holo-ospf:grace", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/areas/area/interfaces/interface/database/link-scope-lsa-type/link-scope-lsas/link-scope-lsa/ospfv3/body/ietf-ospfv3-extended-lsa:e-link", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/areas/area/interfaces/interface/database/link-scope-lsa-type/link-scope-lsas/link-scope-lsa/ospfv3/body/ietf-ospfv3-extended-lsa:e-link/lsa-options", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/areas/area/interfaces/interface/database/link-scope-lsa-type/link-scope-lsas/link-scope-lsa/ospfv3/body/ietf-ospfv3-extended-lsa:e-link/e-link-tlvs", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/areas/area/interfaces/interface/database/link-scope-lsa-type/link-scope-lsas/link-scope-lsa/ospfv3/body/ietf-ospfv3-extended-lsa:e-link/e-link-tlvs/unknown-tlv", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/areas/area/interfaces/interface/database/link-scope-lsa-type/link-scope-lsas/link-scope-lsa/ospfv3/body/ietf-ospfv3-extended-lsa:e-link/e-link-tlvs/intra-prefix-tlv", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/areas/area/interfaces/interface/database/link-scope-lsa-type/link-scope-lsas/link-scope-lsa/ospfv3/body/ietf-ospfv3-extended-lsa:e-link/e-link-tlvs/intra-prefix-tlv/prefix-options", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/areas/area/interfaces/interface/database/link-scope-lsa-type/link-scope-lsas/link-scope-lsa/ospfv3/body/ietf-ospfv3-extended-lsa:e-link/e-link-tlvs/intra-prefix-tlv/sub-tlvs", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/areas/area/interfaces/interface/database/link-scope-lsa-type/link-scope-lsas/link-scope-lsa/ospfv3/body/ietf-ospfv3-extended-lsa:e-link/e-link-tlvs/intra-prefix-tlv/sub-tlvs/unknown-sub-tlv", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/areas/area/interfaces/interface/database/link-scope-lsa-type/link-scope-lsas/link-scope-lsa/ospfv3/body/ietf-ospfv3-extended-lsa:e-link/e-link-tlvs/intra-prefix-tlv/sub-tlvs/ietf-ospf-sr-mpls:prefix-sid-sub-tlvs/prefix-sid-sub-tlv", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/areas/area/interfaces/interface/database/link-scope-lsa-type/link-scope-lsas/link-scope-lsa/ospfv3/body/ietf-ospfv3-extended-lsa:e-link/e-link-tlvs/intra-prefix-tlv/sub-tlvs/ietf-ospf-sr-mpls:prefix-sid-sub-tlvs/prefix-sid-sub-tlv/ospfv3-prefix-sid-flags", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/areas/area/interfaces/interface/database/link-scope-lsa-type/link-scope-lsas/link-scope-lsa/ospfv3/body/ietf-ospfv3-extended-lsa:e-link/e-link-tlvs/ipv6-link-local-addr-tlv", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/areas/area/interfaces/interface/database/link-scope-lsa-type/link-scope-lsas/link-scope-lsa/ospfv3/body/ietf-ospfv3-extended-lsa:e-link/e-link-tlvs/ipv6-link-local-addr-tlv/sub-tlvs", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/areas/area/interfaces/interface/database/link-scope-lsa-type/link-scope-lsas/link-scope-lsa/ospfv3/body/ietf-ospfv3-extended-lsa:e-link/e-link-tlvs/ipv6-link-local-addr-tlv/sub-tlvs/unknown-sub-tlv", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/areas/area/interfaces/interface/database/link-scope-lsa-type/link-scope-lsas/link-scope-lsa/ospfv3/body/ietf-ospfv3-extended-lsa:e-link/e-link-tlvs/ipv4-link-local-addr-tlv", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/areas/area/interfaces/interface/database/link-scope-lsa-type/link-scope-lsas/link-scope-lsa/ospfv3/body/ietf-ospfv3-extended-lsa:e-link/e-link-tlvs/ipv4-link-local-addr-tlv/sub-tlvs", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-ospf:ospf/areas/area/interfaces/interface/database/link-scope-lsa-type/link-scope-lsas/link-scope-lsa/ospfv3/body/ietf-ospfv3-extended-lsa:e-link/e-link-tlvs/ipv4-link-local-addr-tlv/sub-tlvs/unknown-sub-tlv", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-rip:rip", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-rip:rip/interfaces/interface", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-rip:rip/interfaces/interface/statistics", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-rip:rip/statistics", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-rip:rip/ipv4/neighbors/neighbor", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-rip:rip/ipv4/routes/route", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-rip:rip", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-rip:rip/interfaces/interface", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-rip:rip/interfaces/interface/statistics", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-rip:rip/statistics", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-rip:rip/ipv6/neighbors/neighbor", -) -YangPath( - "/ietf-routing:routing/control-plane-protocols/control-plane-protocol/ietf-rip:rip/ipv6/routes/route", -)