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