Skip to content

Commit 6dddc0c

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

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.
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
// SPDX-License-Identifier: MIT
2+
3+
use std::fmt::Display;
4+
5+
const GRE_CSUM: u16 = 0x8000;
6+
const GRE_ROUTING: u16 = 0x4000;
7+
const GRE_KEY: u16 = 0x2000;
8+
const GRE_SEQ: u16 = 0x1000;
9+
const GRE_STRICT: u16 = 0x0800;
10+
const GRE_REC: u16 = 0x0700;
11+
const GRE_ACK: u16 = 0x0080;
12+
const GRE_FLAGS: u16 = 0x0078;
13+
const GRE_VERSION: u16 = 0x0007;
14+
15+
const TUNNEL_ENCAP_FLAG_CSUM: u16 = 0x0100;
16+
const TUNNEL_ENCAP_FLAG_CSUM6: u16 = 0x0200;
17+
const TUNNEL_ENCAP_FLAG_REMCSUM: u16 = 0x0400;
18+
19+
bitflags! {
20+
#[derive(Clone, Eq, PartialEq, Debug, Copy, Default)]
21+
#[non_exhaustive]
22+
pub struct GreIOFlags: u16 {
23+
const Checksum = GRE_CSUM;
24+
const Routing = GRE_ROUTING;
25+
const Key = GRE_KEY;
26+
const Seq = GRE_SEQ;
27+
const Strict0 = GRE_STRICT;
28+
const Rec = GRE_REC;
29+
const Ack = GRE_ACK;
30+
const Flags = GRE_FLAGS;
31+
const Version = GRE_VERSION;
32+
33+
const _ = !0;
34+
}
35+
36+
#[derive(Clone, Eq, PartialEq, Debug, Copy, Default)]
37+
#[non_exhaustive]
38+
pub struct GreEncapFlags: u16 {
39+
const Checksum = TUNNEL_ENCAP_FLAG_CSUM;
40+
const Checksum6 = TUNNEL_ENCAP_FLAG_CSUM6;
41+
const RemoteChecksum = TUNNEL_ENCAP_FLAG_REMCSUM;
42+
43+
const _ = !0;
44+
}
45+
}
46+
47+
const TUNNEL_ENCAP_NONE: u16 = 0;
48+
const TUNNEL_ENCAP_FOU: u16 = 1;
49+
const TUNNEL_ENCAP_GUE: u16 = 2;
50+
51+
#[derive(Debug, PartialEq, Eq, Clone, Copy, Default)]
52+
#[non_exhaustive]
53+
pub enum GreEncapType {
54+
#[default]
55+
None,
56+
Fou,
57+
Gue,
58+
Other(u16),
59+
}
60+
impl From<u16> for GreEncapType {
61+
fn from(d: u16) -> Self {
62+
match d {
63+
TUNNEL_ENCAP_NONE => GreEncapType::None,
64+
TUNNEL_ENCAP_FOU => GreEncapType::Fou,
65+
TUNNEL_ENCAP_GUE => GreEncapType::Gue,
66+
_ => Self::Other(d),
67+
}
68+
}
69+
}
70+
impl From<&GreEncapType> for u16 {
71+
fn from(t: &GreEncapType) -> Self {
72+
match t {
73+
GreEncapType::None => TUNNEL_ENCAP_NONE,
74+
GreEncapType::Fou => TUNNEL_ENCAP_FOU,
75+
GreEncapType::Gue => TUNNEL_ENCAP_GUE,
76+
GreEncapType::Other(d) => *d,
77+
}
78+
}
79+
}
80+
81+
impl Display for GreEncapType {
82+
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
83+
match self {
84+
GreEncapType::None => write!(f, "none"),
85+
GreEncapType::Fou => write!(f, "fou"),
86+
GreEncapType::Gue => write!(f, "gue"),
87+
GreEncapType::Other(d) => write!(f, "other({d})"),
88+
}
89+
}
90+
}
91+
92+
pub(super) const IFLA_GRE_LINK: u16 = 1;
93+
pub(super) const IFLA_GRE_IFLAGS: u16 = 2;
94+
pub(super) const IFLA_GRE_OFLAGS: u16 = 3;
95+
pub(super) const IFLA_GRE_IKEY: u16 = 4;
96+
pub(super) const IFLA_GRE_OKEY: u16 = 5;
97+
pub(super) const IFLA_GRE_LOCAL: u16 = 6;
98+
pub(super) const IFLA_GRE_REMOTE: u16 = 7;
99+
pub(super) const IFLA_GRE_TTL: u16 = 8;
100+
pub(super) const IFLA_GRE_TOS: u16 = 9;
101+
pub(super) const IFLA_GRE_PMTUDISC: u16 = 10;
102+
pub(super) const IFLA_GRE_ENCAP_LIMIT: u16 = 11;
103+
pub(super) const IFLA_GRE_FLOWINFO: u16 = 12;
104+
pub(super) const IFLA_GRE_FLAGS: u16 = 13;
105+
pub(super) const IFLA_GRE_ENCAP_TYPE: u16 = 14;
106+
pub(super) const IFLA_GRE_ENCAP_FLAGS: u16 = 15;
107+
pub(super) const IFLA_GRE_ENCAP_SPORT: u16 = 16;
108+
pub(super) const IFLA_GRE_ENCAP_DPORT: u16 = 17;
109+
pub(super) const IFLA_GRE_COLLECT_METADATA: u16 = 18;
110+
pub(super) const IFLA_GRE_FWMARK: u16 = 20;

src/link/link_info/gre/info_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)