Skip to content

Commit

Permalink
routing: introduce support for opaque route attributes
Browse files Browse the repository at this point in the history
This change allows protocol crates to install routes with opaque
attributes in the RIB. These attributes can be useful both for
implementing advanced routing policies as well as aiding in
network troubleshooting.

Signed-off-by: Renato Westphal <renato@opensourcerouting.org>
  • Loading branch information
rwestphal committed Nov 4, 2023
1 parent 7086658 commit 0f3ca99
Show file tree
Hide file tree
Showing 11 changed files with 88 additions and 39 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@ Holo supports the following IETF RFCs and Internet drafts:
| ietf-mpls-ldp@2022-03-14 | 86.96% | 92.31% | 100.00% | 100.00% | [92.38%](http://westphal.com.br/holo/ietf-mpls-ldp.html) |
| ietf-mpls@2020-12-18 | 0.00% | 57.14% | - | - | [35.29%](http://westphal.com.br/holo/ietf-mpls.html) |
| ietf-ospf-sr@2023-07-09 | 25.00% | 53.95% | - | - | [52.81%](http://westphal.com.br/holo/ietf-ospf-sr.html) |
| ietf-ospf@2022-10-19 | 75.00% | 59.36% | 100.00% | 41.94% | [59.33%](http://westphal.com.br/holo/ietf-ospf.html) |
| ietf-ospf@2022-10-19 | 75.00% | 59.64% | 100.00% | 41.94% | [59.57%](http://westphal.com.br/holo/ietf-ospf.html) |
| ietf-ospfv3-extended-lsa@2023-08-21 | 50.00% | 85.28% | - | - | [84.85%](http://westphal.com.br/holo/ietf-ospfv3-extended-lsa.html) |
| ietf-rip@2020-02-20 | 27.91% | 93.33% | 100.00% | - | [55.41%](http://westphal.com.br/holo/ietf-rip.html) |
| ietf-routing-policy@2021-10-11 | 100.00% | 0.00% | - | - | [98.11%](http://westphal.com.br/holo/ietf-routing-policy.html) |
Expand Down
12 changes: 0 additions & 12 deletions holo-ospf/src/northbound/yang.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ use crate::packet::tlv::{
AdjSidFlags, GrReason, PrefixSidFlags, RouterInfoCaps,
};
use crate::packet::PacketType;
use crate::route::PathType;
use crate::spf::SpfLogType;
use crate::{ospfv2, ospfv3, spf};

Expand Down Expand Up @@ -97,17 +96,6 @@ impl ToYang for SpfLogType {
}
}

impl ToYang for PathType {
fn to_yang(&self) -> String {
match self {
PathType::IntraArea => "intra-area".to_owned(),
PathType::InterArea => "inter-area".to_owned(),
PathType::Type1External => "external-1".to_owned(),
PathType::Type2External => "external-2".to_owned(),
}
}
}

impl ToYang for InterfaceCfgError {
fn to_yang(&self) -> String {
match self {
Expand Down
13 changes: 3 additions & 10 deletions holo-ospf/src/route.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ use bitflags::bitflags;
use derive_new::new;
use holo_utils::ip::IpAddrKind;
use holo_utils::mpls::Label;
use holo_utils::southbound::OspfRouteType;
use holo_utils::sr::IgpAlgoType;

use crate::area::Area;
Expand Down Expand Up @@ -84,15 +85,6 @@ pub struct SummaryRtr<V: Version> {
pub metric: u32,
}

// OSPF path types in decreasing order of preference.
#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
pub enum PathType {
IntraArea,
InterArea,
Type1External,
Type2External,
}

// Route nexthop key.
#[derive(Clone, Copy, Debug, Eq, new, Ord, PartialEq, PartialOrd)]
pub struct NexthopKey<I: IpAddrKind> {
Expand All @@ -116,8 +108,9 @@ pub struct Nexthop<I: IpAddrKind> {
pub sr_label: Option<Label>,
}

// Ordered list of nexthops.
// Type aliases.
pub type Nexthops<I: IpAddrKind> = BTreeMap<NexthopKey<I>, Nexthop<I>>;
pub type PathType = OspfRouteType;

// ===== impl RouteNet =====

Expand Down
4 changes: 4 additions & 0 deletions holo-ospf/src/southbound/tx.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ use holo_utils::ibus::{IbusMsg, IbusSender};
use holo_utils::mpls::Label;
use holo_utils::southbound::{
LabelInstallMsg, LabelUninstallMsg, Nexthop, RouteKeyMsg, RouteMsg,
RouteOpaqueAttrs,
};

use crate::collections::Arena;
Expand Down Expand Up @@ -66,6 +67,9 @@ pub(crate) fn route_install<V>(
distance: distance.into(),
metric: route.metric(),
tag: route.tag,
opaque_attrs: RouteOpaqueAttrs::Ospf {
route_type: route.path_type,
},
nexthops: nexthops.clone(),
};
let msg = IbusMsg::RouteIpAdd(msg);
Expand Down
5 changes: 4 additions & 1 deletion holo-rip/src/southbound/tx.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@
//

use holo_utils::ibus::{IbusMsg, IbusSender};
use holo_utils::southbound::{Nexthop, RouteKeyMsg, RouteMsg};
use holo_utils::southbound::{
Nexthop, RouteKeyMsg, RouteMsg, RouteOpaqueAttrs,
};

use crate::route::{Route, RouteType};
use crate::version::Version;
Expand All @@ -31,6 +33,7 @@ pub(crate) fn route_install<V>(
distance: distance.into(),
metric: route.metric.get() as u32,
tag: Some(route.tag.into()),
opaque_attrs: RouteOpaqueAttrs::None,
nexthops: [Nexthop::Address {
ifindex: route.ifindex,
addr: route.nexthop.unwrap().into(),
Expand Down
1 change: 1 addition & 0 deletions holo-routing/src/ibus.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ pub(crate) fn notify_redistribute_add(
distance: route.distance,
metric: route.metric,
tag: route.tag,
opaque_attrs: route.opaque_attrs.clone(),
nexthops: route.nexthops.clone(),
};
let msg = IbusMsg::RouteRedistributeAdd(msg);
Expand Down
5 changes: 4 additions & 1 deletion holo-routing/src/northbound/configuration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,9 @@ use holo_utils::ibus::{IbusMsg, SrCfgEvent};
use holo_utils::ip::{AddressFamily, IpNetworkKind};
use holo_utils::mpls::LabelRange;
use holo_utils::protocol::Protocol;
use holo_utils::southbound::{Nexthop, NexthopSpecial, RouteKeyMsg, RouteMsg};
use holo_utils::southbound::{
Nexthop, NexthopSpecial, RouteKeyMsg, RouteMsg, RouteOpaqueAttrs,
};
use holo_utils::sr::{IgpAlgoType, SidLastHopBehavior, SrCfgPrefixSid};
use holo_utils::yang::DataNodeRefExt;
use holo_yang::TryFromYang;
Expand Down Expand Up @@ -821,6 +823,7 @@ impl Provider for Master {
distance: 1,
metric: 0,
tag: None,
opaque_attrs: RouteOpaqueAttrs::None,
nexthops,
};

Expand Down
30 changes: 29 additions & 1 deletion holo-routing/src/northbound/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ use holo_northbound::state::{
};
use holo_northbound::{CallbackKey, NbDaemonSender};
use holo_utils::mpls::Label;
use holo_utils::southbound::Nexthop;
use holo_utils::protocol::Protocol;
use holo_utils::southbound::{Nexthop, RouteOpaqueAttrs};
use holo_yang::ToYang;
use ipnetwork::{Ipv4Network, Ipv6Network};

Expand Down Expand Up @@ -348,6 +349,33 @@ fn load_callbacks() -> Callbacks<Master> {
// TODO: implement me!
None
})
.path(ribs::rib::routes::route::metric::PATH)
.get_element_u32(|_master, args| {
let (_, route) = args.list_entry.as_route().unwrap();
if matches!(route.protocol, Protocol::OSPFV2 | Protocol::OSPFV3) {
Some(route.metric)
} else {
None
}
})
.path(ribs::rib::routes::route::tag::PATH)
.get_element_u32(|_master, args| {
let (_, route) = args.list_entry.as_route().unwrap();
if matches!(route.protocol, Protocol::OSPFV2 | Protocol::OSPFV3) {
route.tag
} else {
None
}
})
.path(ribs::rib::routes::route::route_type::PATH)
.get_element_string(|_master, args| {
let (_, route) = args.list_entry.as_route().unwrap();
if let RouteOpaqueAttrs::Ospf { route_type } = &route.opaque_attrs {
Some(route_type.to_yang())
} else {
None
}
})
.build()
}

Expand Down
7 changes: 6 additions & 1 deletion holo-routing/src/rib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ use holo_utils::mpls::Label;
use holo_utils::protocol::Protocol;
use holo_utils::southbound::{
AddressFlags, AddressMsg, LabelInstallMsg, LabelUninstallMsg, Nexthop,
NexthopSpecial, RouteKeyMsg, RouteMsg,
NexthopSpecial, RouteKeyMsg, RouteMsg, RouteOpaqueAttrs,
};
use holo_utils::{UnboundedReceiver, UnboundedSender};
use ipnetwork::{IpNetwork, Ipv4Network, Ipv6Network};
Expand All @@ -41,6 +41,7 @@ pub struct Route {
pub distance: u32,
pub metric: u32,
pub tag: Option<u32>,
pub opaque_attrs: RouteOpaqueAttrs,
pub nexthops: BTreeSet<Nexthop>,
pub last_updated: DateTime<Utc>,
pub flags: RouteFlags,
Expand Down Expand Up @@ -88,6 +89,7 @@ impl Rib {
distance,
0,
None,
RouteOpaqueAttrs::None,
Default::default(),
Utc::now(),
RouteFlags::empty(),
Expand Down Expand Up @@ -139,6 +141,7 @@ impl Rib {
msg.distance,
msg.metric,
msg.tag,
msg.opaque_attrs,
msg.nexthops,
Utc::now(),
RouteFlags::empty(),
Expand All @@ -151,6 +154,7 @@ impl Rib {
route.distance = msg.distance;
route.metric = msg.metric;
route.tag = msg.tag;
route.opaque_attrs = msg.opaque_attrs;
route.nexthops = msg.nexthops;
route.last_updated = Utc::now();
route.flags.remove(RouteFlags::REMOVED);
Expand Down Expand Up @@ -188,6 +192,7 @@ impl Rib {
0,
0,
None,
RouteOpaqueAttrs::None,
msg.nexthops.clone(),
Utc::now(),
RouteFlags::empty(),
Expand Down
36 changes: 36 additions & 0 deletions holo-utils/src/southbound.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,8 @@ pub struct RouteMsg {
pub distance: u32,
pub metric: u32,
pub tag: Option<u32>,
#[serde(skip)]
pub opaque_attrs: RouteOpaqueAttrs,
pub nexthops: BTreeSet<Nexthop>,
}

Expand Down Expand Up @@ -112,6 +114,27 @@ pub struct LabelUninstallMsg {
pub route: Option<(Protocol, IpNetwork)>,
}

// Route opaque attributes.
#[derive(Clone, Debug, Default)]
#[derive(Deserialize, Serialize)]
pub enum RouteOpaqueAttrs {
#[default]
None,
Ospf {
route_type: OspfRouteType,
},
}

// OSPF route types in decreasing order of preference.
#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
#[derive(Deserialize, Serialize)]
pub enum OspfRouteType {
IntraArea,
InterArea,
Type1External,
Type2External,
}

// ===== impl Nexthop =====

impl Nexthop {
Expand Down Expand Up @@ -192,3 +215,16 @@ impl TryFromYang for NexthopSpecial {
}
}
}

// ===== impl OspfRouteType =====

impl ToYang for OspfRouteType {
fn to_yang(&self) -> String {
match self {
OspfRouteType::IntraArea => "intra-area".to_owned(),
OspfRouteType::InterArea => "inter-area".to_owned(),
OspfRouteType::Type1External => "external-1".to_owned(),
OspfRouteType::Type2External => "external-2".to_owned(),
}
}
}
12 changes: 0 additions & 12 deletions holo-yang/modules/deviations/ietf-ospf-holo-deviations.yang
Original file line number Diff line number Diff line change
Expand Up @@ -3271,16 +3271,4 @@ module ietf-ospf-holo-deviations {
deviate not-supported;
}
*/

deviation "/rt:routing/rt:ribs/rt:rib/rt:routes/rt:route/ospf:metric" {
deviate not-supported;
}

deviation "/rt:routing/rt:ribs/rt:rib/rt:routes/rt:route/ospf:tag" {
deviate not-supported;
}

deviation "/rt:routing/rt:ribs/rt:rib/rt:routes/rt:route/ospf:route-type" {
deviate not-supported;
}
}

0 comments on commit 0f3ca99

Please sign in to comment.