Skip to content
This repository has been archived by the owner on Oct 26, 2022. It is now read-only.

MPLS constants and NLAs #233

Merged
merged 2 commits into from
Feb 13, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions netlink-packet-route/src/rtnl/constants.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1201,3 +1201,17 @@ pub const IFLA_XDP_PROG_ID: u32 = 4;
// pub const PREFIX_UNSPEC: int = 0;
// pub const PREFIX_ADDRESS: int = 1;
// pub const PREFIX_CACHEINFO: int = 2;

pub const LWTUNNEL_ENCAP_NONE: u16 = 0;
pub const LWTUNNEL_ENCAP_MPLS: u16 = 1;
pub const LWTUNNEL_ENCAP_IP: u16 = 2;
pub const LWTUNNEL_ENCAP_ILA: u16 = 3;
pub const LWTUNNEL_ENCAP_IP6: u16 = 4;
pub const LWTUNNEL_ENCAP_SEG6: u16 = 5;
pub const LWTUNNEL_ENCAP_BPF: u16 = 6;
pub const LWTUNNEL_ENCAP_SEG6_LOCAL: u16 = 7;
pub const LWTUNNEL_ENCAP_RPL: u16 = 8;

pub const MPLS_IPTUNNEL_UNSPEC: u16 = 0;
pub const MPLS_IPTUNNEL_DST: u16 = 1;
pub const MPLS_IPTUNNEL_TTL: u16 = 2;
3 changes: 3 additions & 0 deletions netlink-packet-route/src/rtnl/route/nlas/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ pub use self::metrics::*;
mod mfc_stats;
pub use self::mfc_stats::*;

mod mpls_ip_tunnel;
pub use self::mpls_ip_tunnel::*;

mod next_hops;
pub use self::next_hops::*;

Expand Down
59 changes: 59 additions & 0 deletions netlink-packet-route/src/rtnl/route/nlas/mpls_ip_tunnel.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
// SPDX-License-Identifier: MIT

use anyhow::Context;

use crate::{
constants::*,
nlas::{DefaultNla, Nla, NlaBuffer},
parsers::parse_u8,
traits::Parseable,
DecodeError,
};

/// Netlink attributes for `RTA_ENCAP` with `RTA_ENCAP_TYPE` set to `LWTUNNEL_ENCAP_MPLS`.
pub enum MplsIpTunnel {
Destination(Vec<u8>),
Ttl(u8),
Other(DefaultNla),
}

impl Nla for MplsIpTunnel {
fn value_len(&self) -> usize {
use self::MplsIpTunnel::*;
match self {
Destination(bytes) => bytes.len(),
Ttl(_) => 1,
Other(attr) => attr.value_len(),
}
}

fn kind(&self) -> u16 {
use self::MplsIpTunnel::*;
match self {
Destination(_) => MPLS_IPTUNNEL_DST,
Ttl(_) => MPLS_IPTUNNEL_TTL,
Other(attr) => attr.kind(),
}
}

fn emit_value(&self, buffer: &mut [u8]) {
use self::MplsIpTunnel::*;
match self {
Destination(bytes) => buffer.copy_from_slice(bytes.as_slice()),
Ttl(ttl) => buffer[0] = *ttl,
Other(attr) => attr.emit_value(buffer),
}
}
}

impl<'a, T: AsRef<[u8]> + ?Sized> Parseable<NlaBuffer<&'a T>> for MplsIpTunnel {
fn parse(buf: &NlaBuffer<&'a T>) -> Result<Self, DecodeError> {
use self::MplsIpTunnel::*;
let payload = buf.value();
Ok(match buf.kind() {
MPLS_IPTUNNEL_DST => Destination(payload.to_vec()),
MPLS_IPTUNNEL_TTL => Ttl(parse_u8(payload).context("invalid MPLS_IPTUNNEL_TTL value")?),
_ => Other(DefaultNla::parse(buf).context("invalid NLA value (unknown type) value")?),
})
}
}