Skip to content

Commit cf6e5dc

Browse files
committed
Add enum entries to InfoGreTun and InfoGreTun6
Signed-off-by: Julius Rüberg <[email protected]>
1 parent eef9be7 commit cf6e5dc

File tree

11 files changed

+840
-106
lines changed

11 files changed

+840
-106
lines changed

src/link/link_info/gre.rs

Lines changed: 0 additions & 45 deletions
This file was deleted.
File renamed without changes.
File renamed without changes.

src/link/link_info/gre/gre_tun.rs

Lines changed: 184 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,184 @@
1+
// SPDX-License-Identifier: MIT
2+
3+
use std::net::Ipv4Addr;
4+
5+
use crate::ip::parse_ipv4_addr;
6+
use anyhow::Context;
7+
use byteorder::{ByteOrder, NetworkEndian};
8+
use netlink_packet_utils::{
9+
nla::{DefaultNla, Nla, NlaBuffer},
10+
parsers::{parse_u16_be, parse_u32_be, parse_u8},
11+
DecodeError, Parseable,
12+
};
13+
14+
use super::{
15+
GreEncapFlags, GreEncapType, GreIOFlags, IFLA_GRE_COLLECT_METADATA,
16+
IFLA_GRE_ENCAP_DPORT, IFLA_GRE_ENCAP_FLAGS, IFLA_GRE_ENCAP_SPORT,
17+
IFLA_GRE_ENCAP_TYPE, IFLA_GRE_FWMARK, IFLA_GRE_IFLAGS, IFLA_GRE_IKEY,
18+
IFLA_GRE_LOCAL, IFLA_GRE_OFLAGS, IFLA_GRE_OKEY, IFLA_GRE_PMTUDISC,
19+
IFLA_GRE_REMOTE, IFLA_GRE_TOS, IFLA_GRE_TTL, IFLA_GRE_UNSPEC,
20+
};
21+
22+
#[derive(Debug, PartialEq, Eq, Clone)]
23+
#[non_exhaustive]
24+
pub enum InfoGreTun {
25+
Unspec,
26+
//Link,
27+
IFlags(GreIOFlags),
28+
OFlags(GreIOFlags),
29+
IKey(u32),
30+
OKey(u32),
31+
Local(Ipv4Addr),
32+
Remote(Ipv4Addr),
33+
Ttl(u8),
34+
Tos(u8),
35+
PathMTUDiscovery(bool),
36+
//Flags,
37+
EncapType(GreEncapType),
38+
EncapFlags(GreEncapFlags),
39+
SourcePort(u16),
40+
DestinationPort(u16),
41+
CollectMetadata,
42+
FwMask(u32),
43+
Other(DefaultNla),
44+
}
45+
46+
impl Nla for InfoGreTun {
47+
fn value_len(&self) -> usize {
48+
match self {
49+
Self::Unspec => 0,
50+
Self::IFlags(_) | Self::OFlags(_) => const { size_of::<u16>() },
51+
Self::IKey(_) | Self::OKey(_) => const { size_of::<u32>() },
52+
Self::Local(_) | Self::Remote(_) => const { size_of::<Ipv4Addr>() },
53+
Self::Ttl(_) | Self::Tos(_) | Self::PathMTUDiscovery(_) => {
54+
const { size_of::<u8>() }
55+
}
56+
Self::EncapType(_) => const { size_of::<GreEncapType>() },
57+
Self::EncapFlags(_) => const { size_of::<u16>() },
58+
Self::SourcePort(_) | Self::DestinationPort(_) => {
59+
const { size_of::<u16>() }
60+
}
61+
Self::CollectMetadata => 0,
62+
Self::FwMask(_) => const { size_of::<u32>() },
63+
Self::Other(nla) => nla.value_len(),
64+
}
65+
}
66+
67+
fn emit_value(&self, buffer: &mut [u8]) {
68+
match self {
69+
Self::Unspec => {}
70+
Self::IFlags(flags) | Self::OFlags(flags) => {
71+
NetworkEndian::write_u16(buffer, flags.bits())
72+
}
73+
Self::IKey(key) | Self::OKey(key) => {
74+
NetworkEndian::write_u32(buffer, *key)
75+
}
76+
Self::Local(ip) | Self::Remote(ip) => {
77+
buffer.copy_from_slice(&ip.octets());
78+
}
79+
Self::Ttl(value) | Self::Tos(value) => buffer[0] = *value,
80+
Self::PathMTUDiscovery(discover) => {
81+
buffer[0] = if *discover { 1 } else { 0 }
82+
}
83+
Self::EncapType(t) => NetworkEndian::write_u16(buffer, *t as u16),
84+
Self::EncapFlags(flags) => {
85+
NetworkEndian::write_u16(buffer, flags.bits())
86+
}
87+
Self::SourcePort(port) | Self::DestinationPort(port) => {
88+
NetworkEndian::write_u16(buffer, *port)
89+
}
90+
Self::CollectMetadata => {}
91+
Self::FwMask(fw_mask) => NetworkEndian::write_u32(buffer, *fw_mask),
92+
Self::Other(nla) => nla.emit_value(buffer),
93+
}
94+
}
95+
96+
fn kind(&self) -> u16 {
97+
match self {
98+
Self::Unspec => IFLA_GRE_UNSPEC,
99+
Self::IFlags(_) => IFLA_GRE_IFLAGS,
100+
Self::OFlags(_) => IFLA_GRE_OFLAGS,
101+
Self::IKey(_) => IFLA_GRE_IKEY,
102+
Self::Local(_) => IFLA_GRE_LOCAL,
103+
Self::Remote(_) => IFLA_GRE_REMOTE,
104+
Self::OKey(_) => IFLA_GRE_OKEY,
105+
Self::Ttl(_) => IFLA_GRE_TTL,
106+
Self::Tos(_) => IFLA_GRE_TOS,
107+
Self::PathMTUDiscovery(_) => IFLA_GRE_PMTUDISC,
108+
Self::EncapType(_) => IFLA_GRE_ENCAP_TYPE,
109+
Self::EncapFlags(_) => IFLA_GRE_ENCAP_FLAGS,
110+
Self::SourcePort(_) => IFLA_GRE_ENCAP_SPORT,
111+
Self::DestinationPort(_) => IFLA_GRE_ENCAP_DPORT,
112+
Self::CollectMetadata => IFLA_GRE_COLLECT_METADATA,
113+
Self::FwMask(_) => IFLA_GRE_FWMARK,
114+
Self::Other(nla) => nla.kind(),
115+
}
116+
}
117+
}
118+
119+
impl<'a, T: AsRef<[u8]> + ?Sized> Parseable<NlaBuffer<&'a T>> for InfoGreTun {
120+
fn parse(buf: &NlaBuffer<&'a T>) -> Result<Self, DecodeError> {
121+
let payload = buf.value();
122+
Ok(match buf.kind() {
123+
IFLA_GRE_UNSPEC => Self::Unspec,
124+
IFLA_GRE_IFLAGS => Self::IFlags(GreIOFlags::from_bits_retain(
125+
parse_u16_be(payload)
126+
.context("invalid IFLA_GRE_IFLAGS value")?,
127+
)),
128+
IFLA_GRE_OFLAGS => Self::OFlags(GreIOFlags::from_bits_retain(
129+
parse_u16_be(payload)
130+
.context("invalid IFLA_GRE_OFLAGS value")?,
131+
)),
132+
IFLA_GRE_IKEY => Self::IKey(
133+
parse_u32_be(payload).context("invalid IFLA_GRE_IKEY value")?,
134+
),
135+
IFLA_GRE_OKEY => Self::OKey(
136+
parse_u32_be(payload).context("invalid IFLA_GRE_OKEY value")?,
137+
),
138+
IFLA_GRE_LOCAL => Self::Local(
139+
parse_ipv4_addr(payload)
140+
.context("invalid IFLA_GRE_LOCAL value")?,
141+
),
142+
IFLA_GRE_REMOTE => Self::Remote(
143+
parse_ipv4_addr(payload)
144+
.context("invalid IFLA_GRE_LOCAL value")?,
145+
),
146+
IFLA_GRE_TTL => Self::Ttl(
147+
parse_u8(payload).context("invalid IFLA_GRE_TTL value")?,
148+
),
149+
IFLA_GRE_TOS => Self::Tos(
150+
parse_u8(payload).context("invalid IFLA_GRE_TOS value")?,
151+
),
152+
IFLA_GRE_PMTUDISC => Self::PathMTUDiscovery(
153+
parse_u8(payload).context("invalid IFLA_GRE_TOS value")? == 1,
154+
),
155+
IFLA_GRE_ENCAP_TYPE => Self::EncapType(GreEncapType::try_from(
156+
parse_u16_be(payload)
157+
.context("invalid IFLA_GRE_ENCAP_TYPE value")?,
158+
)?),
159+
IFLA_GRE_ENCAP_FLAGS => {
160+
Self::EncapFlags(GreEncapFlags::from_bits_retain(
161+
parse_u16_be(payload)
162+
.context("invalid IFLA_GRE_ENCAP_FLAGS value")?,
163+
))
164+
}
165+
IFLA_GRE_ENCAP_SPORT => Self::SourcePort(
166+
parse_u16_be(payload)
167+
.context("invalid IFLA_GRE_ENCAP_SPORT value")?,
168+
),
169+
IFLA_GRE_ENCAP_DPORT => Self::DestinationPort(
170+
parse_u16_be(payload)
171+
.context("invalid IFLA_GRE_ENCAP_DPORT value")?,
172+
),
173+
IFLA_GRE_COLLECT_METADATA => Self::CollectMetadata,
174+
IFLA_GRE_FWMARK => Self::FwMask(
175+
parse_u32_be(payload)
176+
.context("invalid IFLA_GRE_FWMARK value")?,
177+
),
178+
kind => Self::Other(
179+
DefaultNla::parse(buf)
180+
.context(format!("unknown NLA type {kind} for ip6gre"))?,
181+
),
182+
})
183+
}
184+
}

0 commit comments

Comments
 (0)