Skip to content

Commit e297153

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

File tree

13 files changed

+1193
-194
lines changed

13 files changed

+1193
-194
lines changed

src/link/link_info/gre.rs

Lines changed: 0 additions & 43 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: 186 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,186 @@
1+
// SPDX-License-Identifier: MIT
2+
3+
use std::net::Ipv4Addr;
4+
5+
use netlink_packet_core::{
6+
emit_u16_be, emit_u32_be, parse_u16_be, parse_u32_be, parse_u8,
7+
DecodeError, DefaultNla, ErrorContext, Nla, NlaBuffer, Parseable,
8+
};
9+
10+
use super::{
11+
gre_common::{
12+
IFLA_GRE_COLLECT_METADATA, IFLA_GRE_ENCAP_DPORT, IFLA_GRE_ENCAP_FLAGS,
13+
IFLA_GRE_ENCAP_SPORT, IFLA_GRE_ENCAP_TYPE, IFLA_GRE_FWMARK,
14+
IFLA_GRE_IFLAGS, IFLA_GRE_IKEY, IFLA_GRE_LOCAL, IFLA_GRE_OFLAGS,
15+
IFLA_GRE_OKEY, IFLA_GRE_PMTUDISC, IFLA_GRE_REMOTE, IFLA_GRE_TOS,
16+
IFLA_GRE_TTL,
17+
},
18+
GreEncapFlags, GreEncapType, GreIOFlags,
19+
};
20+
use crate::{
21+
ip::parse_ipv4_addr, link::link_info::gre::gre_common::IFLA_GRE_LINK,
22+
};
23+
24+
#[derive(Debug, PartialEq, Eq, Clone)]
25+
#[non_exhaustive]
26+
pub enum InfoGre {
27+
Link(u32),
28+
IFlags(GreIOFlags),
29+
OFlags(GreIOFlags),
30+
IKey(u32),
31+
OKey(u32),
32+
Local(Ipv4Addr),
33+
Remote(Ipv4Addr),
34+
Ttl(u8),
35+
Tos(u8),
36+
PathMTUDiscovery(bool),
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 InfoGre {
47+
fn value_len(&self) -> usize {
48+
match self {
49+
Self::Link(_) => const { size_of::<u32>() },
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::<u16>() },
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::Link(id) => emit_u32_be(buffer, *id).unwrap(),
70+
Self::IFlags(flags) | Self::OFlags(flags) => {
71+
emit_u16_be(buffer, flags.bits()).unwrap()
72+
}
73+
Self::IKey(key) | Self::OKey(key) => {
74+
emit_u32_be(buffer, *key).unwrap()
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) => emit_u16_be(buffer, t.into()).unwrap(),
84+
Self::EncapFlags(flags) => {
85+
emit_u16_be(buffer, flags.bits()).unwrap()
86+
}
87+
Self::SourcePort(port) | Self::DestinationPort(port) => {
88+
emit_u16_be(buffer, *port).unwrap()
89+
}
90+
Self::CollectMetadata => {}
91+
Self::FwMask(fw_mask) => emit_u32_be(buffer, *fw_mask).unwrap(),
92+
Self::Other(nla) => nla.emit_value(buffer),
93+
}
94+
}
95+
96+
fn kind(&self) -> u16 {
97+
match self {
98+
Self::Link(_) => IFLA_GRE_LINK,
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 InfoGre {
120+
fn parse(buf: &NlaBuffer<&'a T>) -> Result<Self, DecodeError> {
121+
let payload = buf.value();
122+
Ok(match buf.kind() {
123+
IFLA_GRE_LINK => Self::Link(
124+
parse_u32_be(payload).context("invalid IFLA_GRE_LINK value")?,
125+
),
126+
IFLA_GRE_IFLAGS => Self::IFlags(GreIOFlags::from_bits_retain(
127+
parse_u16_be(payload)
128+
.context("invalid IFLA_GRE_IFLAGS value")?,
129+
)),
130+
IFLA_GRE_OFLAGS => Self::OFlags(GreIOFlags::from_bits_retain(
131+
parse_u16_be(payload)
132+
.context("invalid IFLA_GRE_OFLAGS value")?,
133+
)),
134+
IFLA_GRE_IKEY => Self::IKey(
135+
parse_u32_be(payload).context("invalid IFLA_GRE_IKEY value")?,
136+
),
137+
IFLA_GRE_OKEY => Self::OKey(
138+
parse_u32_be(payload).context("invalid IFLA_GRE_OKEY value")?,
139+
),
140+
IFLA_GRE_LOCAL => Self::Local(
141+
parse_ipv4_addr(payload)
142+
.context("invalid IFLA_GRE_LOCAL value")?,
143+
),
144+
IFLA_GRE_REMOTE => Self::Remote(
145+
parse_ipv4_addr(payload)
146+
.context("invalid IFLA_GRE_LOCAL value")?,
147+
),
148+
IFLA_GRE_TTL => Self::Ttl(
149+
parse_u8(payload).context("invalid IFLA_GRE_TTL value")?,
150+
),
151+
IFLA_GRE_TOS => Self::Tos(
152+
parse_u8(payload).context("invalid IFLA_GRE_TOS value")?,
153+
),
154+
IFLA_GRE_PMTUDISC => Self::PathMTUDiscovery(
155+
parse_u8(payload).context("invalid IFLA_GRE_TOS value")? == 1,
156+
),
157+
IFLA_GRE_ENCAP_TYPE => Self::EncapType(GreEncapType::from(
158+
parse_u16_be(payload)
159+
.context("invalid IFLA_GRE_ENCAP_TYPE value")?,
160+
)),
161+
IFLA_GRE_ENCAP_FLAGS => {
162+
Self::EncapFlags(GreEncapFlags::from_bits_retain(
163+
parse_u16_be(payload)
164+
.context("invalid IFLA_GRE_ENCAP_FLAGS value")?,
165+
))
166+
}
167+
IFLA_GRE_ENCAP_SPORT => Self::SourcePort(
168+
parse_u16_be(payload)
169+
.context("invalid IFLA_GRE_ENCAP_SPORT value")?,
170+
),
171+
IFLA_GRE_ENCAP_DPORT => Self::DestinationPort(
172+
parse_u16_be(payload)
173+
.context("invalid IFLA_GRE_ENCAP_DPORT value")?,
174+
),
175+
IFLA_GRE_COLLECT_METADATA => Self::CollectMetadata,
176+
IFLA_GRE_FWMARK => Self::FwMask(
177+
parse_u32_be(payload)
178+
.context("invalid IFLA_GRE_FWMARK value")?,
179+
),
180+
kind => Self::Other(
181+
DefaultNla::parse(buf)
182+
.context(format!("unknown NLA type {kind} for ip6gre"))?,
183+
),
184+
})
185+
}
186+
}

0 commit comments

Comments
 (0)