netlink_packet_route/link/link_info/
geneve.rs1use std::net::{Ipv4Addr, Ipv6Addr};
4
5use netlink_packet_core::{
6 emit_u16_be, emit_u32, emit_u32_be, parse_u16_be, parse_u32, parse_u32_be,
7 parse_u8, DecodeError, DefaultNla, ErrorContext, Nla, NlaBuffer, Parseable,
8};
9
10const IFLA_GENEVE_ID: u16 = 1;
11const IFLA_GENEVE_REMOTE: u16 = 2;
12const IFLA_GENEVE_TTL: u16 = 3;
13const IFLA_GENEVE_TOS: u16 = 4;
14const IFLA_GENEVE_PORT: u16 = 5;
15const IFLA_GENEVE_COLLECT_METADATA: u16 = 6;
16const IFLA_GENEVE_REMOTE6: u16 = 7;
17const IFLA_GENEVE_UDP_CSUM: u16 = 8;
18const IFLA_GENEVE_UDP_ZERO_CSUM6_TX: u16 = 9;
19const IFLA_GENEVE_UDP_ZERO_CSUM6_RX: u16 = 10;
20const IFLA_GENEVE_LABEL: u16 = 11;
21const IFLA_GENEVE_TTL_INHERIT: u16 = 12;
22const IFLA_GENEVE_DF: u16 = 13;
23const IFLA_GENEVE_INNER_PROTO_INHERIT: u16 = 14;
24
25const GENEVE_DF_UNSET: u8 = 0;
26const GENEVE_DF_SET: u8 = 1;
27const GENEVE_DF_INHERIT: u8 = 2;
28
29#[derive(Debug, PartialEq, Eq, Clone, Copy)]
30#[non_exhaustive]
31pub enum GeneveDf {
32 Unset,
33 Set,
34 Inherit,
35 Other(u8),
36}
37
38impl From<u8> for GeneveDf {
39 fn from(d: u8) -> Self {
40 match d {
41 GENEVE_DF_UNSET => Self::Unset,
42 GENEVE_DF_SET => Self::Set,
43 GENEVE_DF_INHERIT => Self::Inherit,
44 _ => Self::Other(d),
45 }
46 }
47}
48
49impl From<GeneveDf> for u8 {
50 fn from(d: GeneveDf) -> Self {
51 match d {
52 GeneveDf::Unset => GENEVE_DF_UNSET,
53 GeneveDf::Set => GENEVE_DF_SET,
54 GeneveDf::Inherit => GENEVE_DF_INHERIT,
55 GeneveDf::Other(value) => value,
56 }
57 }
58}
59
60#[derive(Debug, PartialEq, Eq, Clone)]
61#[non_exhaustive]
62pub enum InfoGeneve {
63 Id(u32),
64 Remote(Ipv4Addr),
65 Remote6(Ipv6Addr),
66 Ttl(u8),
67 Tos(u8),
68 Port(u16),
69 CollectMetadata,
70 UdpCsum(bool),
71 UdpZeroCsum6Tx(bool),
72 UdpZeroCsum6Rx(bool),
73 Label(u32),
74 TtlInherit(bool),
75 Df(GeneveDf),
76 InnerProtoInherit,
77 Other(DefaultNla),
78}
79
80impl Nla for InfoGeneve {
81 fn value_len(&self) -> usize {
82 use self::InfoGeneve::*;
83 match self {
84 Id(_) | Remote(_) | Label(_) => 4,
85 Remote6(_) => 16,
86 Ttl(_) | Tos(_) | UdpCsum(_) | UdpZeroCsum6Tx(_)
87 | UdpZeroCsum6Rx(_) | TtlInherit(_) | Df(_) => 1,
88 Port(_) => 2,
89 CollectMetadata | InnerProtoInherit => 0,
90 Other(nla) => nla.value_len(),
91 }
92 }
93
94 fn emit_value(&self, buffer: &mut [u8]) {
95 use self::InfoGeneve::*;
96 match self {
97 Id(value) => emit_u32(buffer, *value).unwrap(),
98 Remote(value) => buffer.copy_from_slice(&value.octets()),
99 Remote6(value) => buffer.copy_from_slice(&value.octets()),
100 Ttl(value) | Tos(value) => buffer[0] = *value,
101 Port(value) => emit_u16_be(buffer, *value).unwrap(),
102 CollectMetadata | InnerProtoInherit => (),
103 UdpCsum(value)
104 | UdpZeroCsum6Tx(value)
105 | UdpZeroCsum6Rx(value)
106 | TtlInherit(value) => buffer[0] = *value as u8,
107 Label(value) => emit_u32_be(buffer, *value).unwrap(),
108 Df(value) => buffer[0] = (*value).into(),
109 Other(nla) => nla.emit_value(buffer),
110 }
111 }
112
113 fn kind(&self) -> u16 {
114 use self::InfoGeneve::*;
115 match self {
116 Id(_) => IFLA_GENEVE_ID,
117 Remote(_) => IFLA_GENEVE_REMOTE,
118 Remote6(_) => IFLA_GENEVE_REMOTE6,
119 Ttl(_) => IFLA_GENEVE_TTL,
120 Tos(_) => IFLA_GENEVE_TOS,
121 Port(_) => IFLA_GENEVE_PORT,
122 CollectMetadata => IFLA_GENEVE_COLLECT_METADATA,
123 UdpCsum(_) => IFLA_GENEVE_UDP_CSUM,
124 UdpZeroCsum6Tx(_) => IFLA_GENEVE_UDP_ZERO_CSUM6_TX,
125 UdpZeroCsum6Rx(_) => IFLA_GENEVE_UDP_ZERO_CSUM6_RX,
126 Label(_) => IFLA_GENEVE_LABEL,
127 TtlInherit(_) => IFLA_GENEVE_TTL_INHERIT,
128 Df(_) => IFLA_GENEVE_DF,
129 InnerProtoInherit => IFLA_GENEVE_INNER_PROTO_INHERIT,
130 Other(nla) => nla.kind(),
131 }
132 }
133}
134
135impl<'a, T: AsRef<[u8]> + ?Sized> Parseable<NlaBuffer<&'a T>> for InfoGeneve {
136 fn parse(buf: &NlaBuffer<&'a T>) -> Result<Self, DecodeError> {
137 use self::InfoGeneve::*;
138 let payload = buf.value();
139 Ok(match buf.kind() {
140 IFLA_GENEVE_ID => {
141 Id(parse_u32(payload)
142 .context("invalid IFLA_GENEVE_ID value")?)
143 }
144 IFLA_GENEVE_REMOTE => {
145 if payload.len() == 4 {
146 let mut data = [0u8; 4];
147 data.copy_from_slice(&payload[0..4]);
148 Remote(Ipv4Addr::from(data))
149 } else {
150 return Err(DecodeError::from(format!(
151 "Invalid IFLA_GENEVE_REMOTE, got unexpected length of \
152 IPv4 address payload {payload:?}"
153 )));
154 }
155 }
156 IFLA_GENEVE_REMOTE6 => {
157 if payload.len() == 16 {
158 let mut data = [0u8; 16];
159 data.copy_from_slice(&payload[0..16]);
160 Remote6(Ipv6Addr::from(data))
161 } else {
162 return Err(DecodeError::from(format!(
163 "Invalid IFLA_GENEVE_REMOTE6, got unexpected length \
164 of IPv6 address payload {payload:?}"
165 )));
166 }
167 }
168 IFLA_GENEVE_TTL => {
169 Ttl(parse_u8(payload)
170 .context("invalid IFLA_GENEVE_TTL value")?)
171 }
172 IFLA_GENEVE_TOS => {
173 Tos(parse_u8(payload)
174 .context("invalid IFLA_GENEVE_TOS value")?)
175 }
176 IFLA_GENEVE_PORT => Port(
177 parse_u16_be(payload)
178 .context("invalid IFLA_GENEVE_PORT value")?,
179 ),
180 IFLA_GENEVE_COLLECT_METADATA => CollectMetadata,
181 IFLA_GENEVE_UDP_CSUM => UdpCsum(
182 parse_u8(payload)
183 .context("invalid IFLA_GENEVE_UDP_CSUM value")?
184 > 0,
185 ),
186 IFLA_GENEVE_UDP_ZERO_CSUM6_TX => UdpZeroCsum6Tx(
187 parse_u8(payload)
188 .context("invalid IFLA_GENEVE_UDP_ZERO_CSUM6_TX value")?
189 > 0,
190 ),
191 IFLA_GENEVE_UDP_ZERO_CSUM6_RX => UdpZeroCsum6Rx(
192 parse_u8(payload)
193 .context("invalid IFLA_GENEVE_UDP_ZERO_CSUM6_RX value")?
194 > 0,
195 ),
196 IFLA_GENEVE_LABEL => Label(
197 parse_u32_be(payload)
198 .context("invalid IFLA_GENEVE_LABEL value")?,
199 ),
200 IFLA_GENEVE_TTL_INHERIT => TtlInherit(
201 parse_u8(payload)
202 .context("invalid IFLA_GENEVE_TTL_INHERIT value")?
203 > 0,
204 ),
205 IFLA_GENEVE_DF => Df(parse_u8(payload)
206 .context("invalid IFLA_GENEVE_DF value")?
207 .into()),
208 IFLA_GENEVE_INNER_PROTO_INHERIT => InnerProtoInherit,
209 kind => Other(
210 DefaultNla::parse(buf)
211 .context(format!("unknown NLA type {kind}"))?,
212 ),
213 })
214 }
215}