Skip to content

Commit 7630867

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

File tree

13 files changed

+1203
-202
lines changed

13 files changed

+1203
-202
lines changed

src/link/link_info/gre.rs

Lines changed: 0 additions & 45 deletions
This file was deleted.

src/link/link_info/gre/gre.rs

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

0 commit comments

Comments
 (0)