Skip to content

Commit a75e419

Browse files
fixup! iptunnel: add support to ipip, ipip6 and ip6ip6 tunnels
1 parent 27d9f7d commit a75e419

File tree

3 files changed

+48
-20
lines changed

3 files changed

+48
-20
lines changed

src/link/link_info/info_data.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use anyhow::Context;
44

55
use netlink_packet_utils::{
66
nla::{Nla, NlaBuffer, NlasIterator},
7-
DecodeError, Emitable, Parseable,
7+
DecodeError, Emitable, Parseable, ParseableParametrized,
88
};
99

1010
use super::super::{
@@ -362,7 +362,8 @@ impl InfoData {
362362
let nla = &nla.context(format!(
363363
"invalid IFLA_INFO_DATA for {kind} {payload:?}"
364364
))?;
365-
let parsed = InfoIpTunnel::parse(nla)?;
365+
let parsed =
366+
InfoIpTunnel::parse_with_param(nla, kind.clone())?;
366367
v.push(parsed);
367368
}
368369
InfoData::IpTunnel(v)

src/link/link_info/iptunnel.rs

Lines changed: 42 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use byteorder::{ByteOrder, NativeEndian};
88
use netlink_packet_utils::{
99
nla::{DefaultNla, Nla, NlaBuffer},
1010
parsers::{parse_u16, parse_u32, parse_u8},
11-
traits::Parseable,
11+
traits::{Parseable, ParseableParametrized},
1212
DecodeError,
1313
};
1414

@@ -45,7 +45,9 @@ pub enum InfoIpTunnel {
4545
Tos(u8),
4646
EncapLimit(u8),
4747
FlowInfo(u32),
48-
Flags(TunnelFlags),
48+
Ipv6SitFlags(u16),
49+
Ipv4Flags(u16),
50+
Ipv6Flags(u32),
4951
Protocol(IpProtocol),
5052
PMtuDisc(bool),
5153
Ipv6RdPrefix(Ipv6Addr),
@@ -70,8 +72,10 @@ impl Nla for InfoIpTunnel {
7072
IpAddr::V4(_) => 4,
7173
IpAddr::V6(_) => 16,
7274
},
73-
Link(_) | FwMark(_) | FlowInfo(_) | Flags(_) => 4,
74-
EncapType(_)
75+
Link(_) | FwMark(_) | FlowInfo(_) | Ipv6Flags(_) => 4,
76+
Ipv6SitFlags(_)
77+
| Ipv4Flags(_)
78+
| EncapType(_)
7579
| EncapFlags(_)
7680
| EncapSPort(_)
7781
| EncapDPort(_)
@@ -92,8 +96,11 @@ impl Nla for InfoIpTunnel {
9296
Link(value) | FwMark(value) | FlowInfo(value) => {
9397
NativeEndian::write_u32(buffer, *value)
9498
}
95-
Flags(f) => {
96-
NativeEndian::write_u32(buffer, f.bits());
99+
Ipv6Flags(val) => {
100+
NativeEndian::write_u32(buffer, *val);
101+
}
102+
Ipv6SitFlags(val) | Ipv4Flags(val) => {
103+
NativeEndian::write_u16(buffer, *val);
97104
}
98105
Local(value) | Remote(value) => match value {
99106
IpAddr::V4(ipv4) => buffer.copy_from_slice(&ipv4.octets()),
@@ -109,7 +116,7 @@ impl Nla for InfoIpTunnel {
109116
| Ipv6RdRelayPrefixLen(value) => {
110117
NativeEndian::write_u16(buffer, *value)
111118
}
112-
Protocol(value) => buffer[0] = i32::from(*value) as u8,
119+
Protocol(value) => buffer[0] = u8::from(*value),
113120
Ttl(value) | Tos(value) | EncapLimit(value) => buffer[0] = *value,
114121
PMtuDisc(value) | CollectMetada(value) => {
115122
buffer[0] = if *value { 1 } else { 0 }
@@ -128,7 +135,7 @@ impl Nla for InfoIpTunnel {
128135
Tos(_) => IFLA_IPTUN_TOS,
129136
EncapLimit(_) => IFLA_IPTUN_ENCAP_LIMIT,
130137
FlowInfo(_) => IFLA_IPTUN_FLOWINFO,
131-
Flags(_) => IFLA_IPTUN_FLAGS,
138+
Ipv6SitFlags(_) | Ipv4Flags(_) | Ipv6Flags(_) => IFLA_IPTUN_FLAGS,
132139
Protocol(_) => IFLA_IPTUN_PROTO,
133140
PMtuDisc(_) => IFLA_IPTUN_PMTUDISC,
134141
Ipv6RdPrefix(_) => IFLA_IPTUN_6RD_PREFIX,
@@ -146,8 +153,13 @@ impl Nla for InfoIpTunnel {
146153
}
147154
}
148155

149-
impl<'a, T: AsRef<[u8]> + ?Sized> Parseable<NlaBuffer<&'a T>> for InfoIpTunnel {
150-
fn parse(buf: &NlaBuffer<&'a T>) -> Result<Self, DecodeError> {
156+
impl<'a, T: AsRef<[u8]> + ?Sized>
157+
ParseableParametrized<NlaBuffer<&'a T>, super::InfoKind> for InfoIpTunnel
158+
{
159+
fn parse_with_param(
160+
buf: &NlaBuffer<&'a T>,
161+
kind: super::InfoKind,
162+
) -> Result<Self, DecodeError> {
151163
use self::InfoIpTunnel::*;
152164
let payload = buf.value();
153165
Ok(match buf.kind() {
@@ -202,12 +214,27 @@ impl<'a, T: AsRef<[u8]> + ?Sized> Parseable<NlaBuffer<&'a T>> for InfoIpTunnel {
202214
parse_u32(payload)
203215
.context("invalid IFLA_IPTUN_FLOWINFO value")?,
204216
),
205-
IFLA_IPTUN_FLAGS => Flags(TunnelFlags::from_bits_retain(
206-
parse_u32(payload).context("invalid IFLA_IPTUN_FLAGS value")?,
207-
)),
217+
IFLA_IPTUN_FLAGS => match kind {
218+
super::InfoKind::SitTun => InfoIpTunnel::Ipv6SitFlags(
219+
parse_u16(payload)
220+
.context("invalid IFLA_IPTUN_FLAGS for SIT")?,
221+
),
222+
super::InfoKind::Tun => InfoIpTunnel::Ipv4Flags(
223+
parse_u16(payload)
224+
.context("invalid IFLA_IPTUN_FLAGS for IPIP")?,
225+
),
226+
super::InfoKind::Ip6Tnl => InfoIpTunnel::Ipv6Flags(
227+
parse_u32(payload)
228+
.context("invalid IFLA_IPTUN_FLAGS for IP6")?,
229+
),
230+
_ => {
231+
return Err(DecodeError::from(format!(
232+
"unsupported InfoKind for IFLA_IPTUN_FLAGS: {kind:?}"
233+
)));
234+
}
235+
},
208236
IFLA_IPTUN_PROTO => Protocol(IpProtocol::from(
209-
parse_u8(payload).context("invalid IFLA_IPTUN_PROTO value")?
210-
as i32,
237+
parse_u8(payload).context("invalid IFLA_IPTUN_PROTO value")?,
211238
)),
212239
IFLA_IPTUN_PMTUDISC => PMtuDisc(
213240
parse_u8(payload)

src/link/tests/iptunnel.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use netlink_packet_utils::{Emitable, Parseable};
88
use crate::link::{
99
InfoData, InfoIpTunnel, InfoKind, LinkAttribute, LinkFlags, LinkHeader,
1010
LinkInfo, LinkLayerType, LinkMessage, LinkMessageBuffer, TunnelEncapFlags,
11-
TunnelEncapType, TunnelFlags,
11+
TunnelEncapType,
1212
};
1313

1414
use crate::{AddressFamily, IpProtocol};
@@ -124,7 +124,7 @@ fn test_iptunnel_ipip6_link_info() {
124124
InfoIpTunnel::Ttl(64),
125125
InfoIpTunnel::EncapLimit(4),
126126
InfoIpTunnel::FlowInfo(0),
127-
InfoIpTunnel::Flags(TunnelFlags::from_bits_retain(0x30000)),
127+
InfoIpTunnel::Ipv6Flags(0x30000),
128128
InfoIpTunnel::Protocol(IpProtocol::Ipip),
129129
InfoIpTunnel::FwMark(0),
130130
InfoIpTunnel::EncapType(TunnelEncapType::None),
@@ -193,7 +193,7 @@ fn test_iptunnel_ip6ip6_link_info() {
193193
InfoIpTunnel::Ttl(64),
194194
InfoIpTunnel::EncapLimit(4),
195195
InfoIpTunnel::FlowInfo(0),
196-
InfoIpTunnel::Flags(TunnelFlags::from_bits_retain(0x30000)),
196+
InfoIpTunnel::Ipv6Flags(0x30000),
197197
InfoIpTunnel::Protocol(IpProtocol::Ipv6),
198198
InfoIpTunnel::FwMark(0),
199199
InfoIpTunnel::EncapType(TunnelEncapType::None),

0 commit comments

Comments
 (0)