netlink_packet_route/rtnl/route/nlas/
mpls_ip_tunnel.rs1use anyhow::Context;
4use netlink_packet_utils::{
5 nla::{DefaultNla, Nla, NlaBuffer},
6 parsers::parse_u8,
7 traits::Parseable,
8 DecodeError,
9};
10
11use crate::constants::*;
12
13#[non_exhaustive]
16pub enum MplsIpTunnel {
17 Destination(Vec<u8>),
18 Ttl(u8),
19 Other(DefaultNla),
20}
21
22impl Nla for MplsIpTunnel {
23 fn value_len(&self) -> usize {
24 use self::MplsIpTunnel::*;
25 match self {
26 Destination(bytes) => bytes.len(),
27 Ttl(_) => 1,
28 Other(attr) => attr.value_len(),
29 }
30 }
31
32 fn kind(&self) -> u16 {
33 use self::MplsIpTunnel::*;
34 match self {
35 Destination(_) => MPLS_IPTUNNEL_DST,
36 Ttl(_) => MPLS_IPTUNNEL_TTL,
37 Other(attr) => attr.kind(),
38 }
39 }
40
41 fn emit_value(&self, buffer: &mut [u8]) {
42 use self::MplsIpTunnel::*;
43 match self {
44 Destination(bytes) => buffer.copy_from_slice(bytes.as_slice()),
45 Ttl(ttl) => buffer[0] = *ttl,
46 Other(attr) => attr.emit_value(buffer),
47 }
48 }
49}
50
51impl<'a, T: AsRef<[u8]> + ?Sized> Parseable<NlaBuffer<&'a T>> for MplsIpTunnel {
52 fn parse(buf: &NlaBuffer<&'a T>) -> Result<Self, DecodeError> {
53 use self::MplsIpTunnel::*;
54 let payload = buf.value();
55 Ok(match buf.kind() {
56 MPLS_IPTUNNEL_DST => Destination(payload.to_vec()),
57 MPLS_IPTUNNEL_TTL => {
58 Ttl(parse_u8(payload)
59 .context("invalid MPLS_IPTUNNEL_TTL value")?)
60 }
61 _ => Other(
62 DefaultNla::parse(buf)
63 .context("invalid NLA value (unknown type) value")?,
64 ),
65 })
66 }
67}