netlink_packet_route/route/
lwtunnel.rs
1use super::{RouteError, RouteMplsIpTunnel};
4use netlink_packet_utils::nla::{DefaultNla, Nla, NlaBuffer, NlasIterator};
5use netlink_packet_utils::traits::{Emitable, Parseable, ParseableParametrized};
6
7const LWTUNNEL_ENCAP_NONE: u16 = 0;
8const LWTUNNEL_ENCAP_MPLS: u16 = 1;
9const LWTUNNEL_ENCAP_IP: u16 = 2;
10const LWTUNNEL_ENCAP_ILA: u16 = 3;
11const LWTUNNEL_ENCAP_IP6: u16 = 4;
12const LWTUNNEL_ENCAP_SEG6: u16 = 5;
13const LWTUNNEL_ENCAP_BPF: u16 = 6;
14const LWTUNNEL_ENCAP_SEG6_LOCAL: u16 = 7;
15const LWTUNNEL_ENCAP_RPL: u16 = 8;
16const LWTUNNEL_ENCAP_IOAM6: u16 = 9;
17const LWTUNNEL_ENCAP_XFRM: u16 = 10;
18
19#[derive(Debug, PartialEq, Eq, Clone, Copy, Default)]
20#[non_exhaustive]
21pub enum RouteLwEnCapType {
22 #[default]
23 None,
24 Mpls,
25 Ip,
26 Ila,
27 Ip6,
28 Seg6,
29 Bpf,
30 Seg6Local,
31 Rpl,
32 Ioam6,
33 Xfrm,
34 Other(u16),
35}
36
37impl From<u16> for RouteLwEnCapType {
38 fn from(d: u16) -> Self {
39 match d {
40 LWTUNNEL_ENCAP_NONE => Self::None,
41 LWTUNNEL_ENCAP_MPLS => Self::Mpls,
42 LWTUNNEL_ENCAP_IP => Self::Ip,
43 LWTUNNEL_ENCAP_ILA => Self::Ila,
44 LWTUNNEL_ENCAP_IP6 => Self::Ip6,
45 LWTUNNEL_ENCAP_SEG6 => Self::Seg6,
46 LWTUNNEL_ENCAP_BPF => Self::Bpf,
47 LWTUNNEL_ENCAP_SEG6_LOCAL => Self::Seg6Local,
48 LWTUNNEL_ENCAP_RPL => Self::Rpl,
49 LWTUNNEL_ENCAP_IOAM6 => Self::Ioam6,
50 LWTUNNEL_ENCAP_XFRM => Self::Xfrm,
51 _ => Self::Other(d),
52 }
53 }
54}
55
56impl From<RouteLwEnCapType> for u16 {
57 fn from(v: RouteLwEnCapType) -> u16 {
58 match v {
59 RouteLwEnCapType::None => LWTUNNEL_ENCAP_NONE,
60 RouteLwEnCapType::Mpls => LWTUNNEL_ENCAP_MPLS,
61 RouteLwEnCapType::Ip => LWTUNNEL_ENCAP_IP,
62 RouteLwEnCapType::Ila => LWTUNNEL_ENCAP_ILA,
63 RouteLwEnCapType::Ip6 => LWTUNNEL_ENCAP_IP6,
64 RouteLwEnCapType::Seg6 => LWTUNNEL_ENCAP_SEG6,
65 RouteLwEnCapType::Bpf => LWTUNNEL_ENCAP_BPF,
66 RouteLwEnCapType::Seg6Local => LWTUNNEL_ENCAP_SEG6_LOCAL,
67 RouteLwEnCapType::Rpl => LWTUNNEL_ENCAP_RPL,
68 RouteLwEnCapType::Ioam6 => LWTUNNEL_ENCAP_IOAM6,
69 RouteLwEnCapType::Xfrm => LWTUNNEL_ENCAP_XFRM,
70 RouteLwEnCapType::Other(d) => d,
71 }
72 }
73}
74
75impl Emitable for RouteLwEnCapType {
76 fn buffer_len(&self) -> usize {
77 2
78 }
79
80 fn emit(&self, buffer: &mut [u8]) {
81 buffer.copy_from_slice(&(u16::from(*self).to_ne_bytes()))
82 }
83}
84
85impl std::fmt::Display for RouteLwEnCapType {
86 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
87 match self {
88 Self::None => write!(f, "none"),
89 Self::Mpls => write!(f, "mpls"),
90 Self::Ip => write!(f, "ip"),
91 Self::Ila => write!(f, "ila"),
92 Self::Ip6 => write!(f, "ip6"),
93 Self::Seg6 => write!(f, "seg6"),
94 Self::Bpf => write!(f, "bpf"),
95 Self::Seg6Local => write!(f, "seg6_local"),
96 Self::Rpl => write!(f, "rpl"),
97 Self::Ioam6 => write!(f, "ioam6"),
98 Self::Xfrm => write!(f, "xfrm"),
99 Self::Other(d) => write!(f, "other({d})"),
100 }
101 }
102}
103
104#[derive(Debug, PartialEq, Eq, Clone)]
105#[non_exhaustive]
106pub enum RouteLwTunnelEncap {
107 Mpls(RouteMplsIpTunnel),
108 Other(DefaultNla),
109}
110
111impl Nla for RouteLwTunnelEncap {
112 fn value_len(&self) -> usize {
113 match self {
114 Self::Mpls(v) => v.value_len(),
115 Self::Other(v) => v.value_len(),
116 }
117 }
118
119 fn emit_value(&self, buffer: &mut [u8]) {
120 match self {
121 Self::Mpls(v) => v.emit_value(buffer),
122 Self::Other(v) => v.emit_value(buffer),
123 }
124 }
125
126 fn kind(&self) -> u16 {
127 match self {
128 Self::Mpls(v) => v.kind(),
129 Self::Other(v) => v.kind(),
130 }
131 }
132}
133
134impl<'a, T> ParseableParametrized<NlaBuffer<&'a T>, RouteLwEnCapType> for RouteLwTunnelEncap
135where
136 T: AsRef<[u8]> + ?Sized,
137{
138 type Error = RouteError;
139 fn parse_with_param(
140 buf: &NlaBuffer<&'a T>,
141 kind: RouteLwEnCapType,
142 ) -> Result<Self, Self::Error> {
143 Ok(match kind {
144 RouteLwEnCapType::Mpls => Self::Mpls(RouteMplsIpTunnel::parse(buf)?),
145 _ => Self::Other(DefaultNla::parse(buf)?),
146 })
147 }
148}
149
150#[derive(Debug, PartialEq, Eq, Clone)]
151#[non_exhaustive]
152pub(crate) struct VecRouteLwTunnelEncap(pub(crate) Vec<RouteLwTunnelEncap>);
153
154impl<'a, T> ParseableParametrized<NlaBuffer<&'a T>, RouteLwEnCapType> for VecRouteLwTunnelEncap
155where
156 T: AsRef<[u8]> + ?Sized,
157{
158 type Error = RouteError;
159 fn parse_with_param(
160 buf: &NlaBuffer<&'a T>,
161 kind: RouteLwEnCapType,
162 ) -> Result<Self, RouteError> {
163 let mut ret = Vec::new();
164 for nla in NlasIterator::new(buf.value()) {
165 let nla = nla.map_err(|error| RouteError::InvalidRtaEncap { error, kind })?;
166 ret.push(RouteLwTunnelEncap::parse_with_param(&nla, kind)?);
167 }
168 Ok(Self(ret))
169 }
170}