Skip to content

Commit 2b274af

Browse files
committed
route: add support for MPLS routes and nexthop label stacks
Extend `RouteMessageBuilder` to support the creation of MPLS routes and nexthops with MPLS label stacks. This enables configuration of IP-to-MPLS, MPLS-to-MPLS, and MPLS-to-IP routes. Signed-off-by: Renato Westphal <[email protected]>
1 parent 47ea04c commit 2b274af

File tree

1 file changed

+66
-1
lines changed

1 file changed

+66
-1
lines changed

src/route/builder.rs

Lines changed: 66 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@ use std::{
77

88
use netlink_packet_route::{
99
route::{
10-
RouteAddress, RouteAttribute, RouteFlags, RouteHeader, RouteMessage,
10+
MplsLabel, RouteAddress, RouteAttribute, RouteFlags, RouteHeader,
11+
RouteLwEnCapType, RouteLwTunnelEncap, RouteMessage, RouteMplsIpTunnel,
1112
RouteProtocol, RouteScope, RouteType,
1213
},
1314
AddressFamily,
@@ -52,6 +53,29 @@ impl<T> RouteMessageBuilder<T> {
5253
self
5354
}
5455

56+
/// Sets the output MPLS encapsulation labels.
57+
pub fn output_mpls(mut self, labels: Vec<MplsLabel>) -> Self {
58+
if labels.is_empty() {
59+
return self;
60+
}
61+
if self.message.header.address_family == AddressFamily::Mpls {
62+
self.message
63+
.attributes
64+
.push(RouteAttribute::NewDestination(labels));
65+
} else {
66+
self.message
67+
.attributes
68+
.push(RouteAttribute::EncapType(RouteLwEnCapType::Mpls));
69+
let encap = RouteLwTunnelEncap::Mpls(
70+
RouteMplsIpTunnel::Destination(labels),
71+
);
72+
self.message
73+
.attributes
74+
.push(RouteAttribute::Encap(vec![encap]));
75+
}
76+
self
77+
}
78+
5579
/// Sets the route priority (metric)
5680
pub fn priority(mut self, priority: u32) -> Self {
5781
self.message
@@ -402,3 +426,44 @@ impl Default for RouteMessageBuilder<IpAddr> {
402426
Self::new()
403427
}
404428
}
429+
430+
impl RouteMessageBuilder<MplsLabel> {
431+
/// Create default RouteMessage with header set to:
432+
/// * route: [RouteHeader::RT_TABLE_MAIN]
433+
/// * protocol: [RouteProtocol::Static]
434+
/// * scope: [RouteScope::Universe]
435+
/// * kind: [RouteType::Unicast]
436+
/// * address_family: [AddressFamily::Mpls]
437+
///
438+
/// For using this message in querying routes, these settings
439+
/// are ignored unless `NETLINK_GET_STRICT_CHK` been enabled.
440+
pub fn new() -> Self {
441+
let mut builder = Self::new_no_address_family();
442+
builder.get_mut().header.address_family = AddressFamily::Mpls;
443+
builder
444+
}
445+
446+
/// Sets the destination MPLS label.
447+
pub fn label(mut self, label: MplsLabel) -> Self {
448+
self.message.header.address_family = AddressFamily::Mpls;
449+
self.message.header.destination_prefix_length = 20;
450+
self.message
451+
.attributes
452+
.push(RouteAttribute::Destination(RouteAddress::Mpls(label)));
453+
self
454+
}
455+
456+
/// Sets the gateway (via) address.
457+
pub fn via(mut self, addr: IpAddr) -> Self {
458+
self.message
459+
.attributes
460+
.push(RouteAttribute::Via(addr.into()));
461+
self
462+
}
463+
}
464+
465+
impl Default for RouteMessageBuilder<MplsLabel> {
466+
fn default() -> Self {
467+
Self::new()
468+
}
469+
}

0 commit comments

Comments
 (0)