netlink_packet_route/tc/actions/
tunnel_key.rs1use crate::ip::{parse_ipv4_addr, parse_ipv6_addr};
4use anyhow::Context;
5use byteorder::{BigEndian, ByteOrder};
10use netlink_packet_utils::{
11 nla::{DefaultNla, Nla, NlaBuffer},
12 parsers::{parse_u16_be, parse_u32_be, parse_u8},
13 traits::{Emitable, Parseable},
14 DecodeError,
15};
16use std::net::{Ipv4Addr, Ipv6Addr};
17
18use super::{
19 TcActionGeneric, TcActionGenericBuffer, Tcf, TcfBuffer, TC_TCF_BUF_LEN,
20};
21
22#[derive(Debug, PartialEq, Eq, Clone)]
23#[non_exhaustive]
24pub struct TcActionTunnelKey {}
25impl TcActionTunnelKey {
26 pub const KIND: &'static str = "tunnel_key";
27}
28
29const TCA_TUNNEL_KEY_TM: u16 = 1;
30const TCA_TUNNEL_KEY_PARMS: u16 = 2;
31const TCA_TUNNEL_KEY_ENC_IPV4_SRC: u16 = 3;
32const TCA_TUNNEL_KEY_ENC_IPV4_DST: u16 = 4;
33const TCA_TUNNEL_KEY_ENC_IPV6_SRC: u16 = 5;
34const TCA_TUNNEL_KEY_ENC_IPV6_DST: u16 = 6;
35const TCA_TUNNEL_KEY_ENC_KEY_ID: u16 = 7;
36const TCA_TUNNEL_KEY_ENC_DST_PORT: u16 = 9;
38const TCA_TUNNEL_KEY_NO_CSUM: u16 = 10;
39const TCA_TUNNEL_KEY_ENC_TOS: u16 = 12;
41const TCA_TUNNEL_KEY_ENC_TTL: u16 = 13;
42#[derive(Debug, PartialEq, Eq, Clone)]
45#[non_exhaustive]
46pub enum TcActionTunnelKeyOption {
47 Tm(Tcf),
48 Parms(TcTunnelKey),
49 EncIpv4Src(Ipv4Addr),
50 EncIpv4Dst(Ipv4Addr),
51 EncIpv6Src(Ipv6Addr),
52 EncIpv6Dst(Ipv6Addr),
53 EncKeyId(u32),
54 EncDstPort(u16),
55 EncTos(u8),
56 EncTtl(u8),
57 NoCsum(bool),
58 Other(DefaultNla),
59}
60
61impl Nla for TcActionTunnelKeyOption {
62 fn value_len(&self) -> usize {
63 match self {
64 Self::Tm(_) => TC_TCF_BUF_LEN,
65 Self::Parms(_) => TC_TUNNEL_KEY_BUF_LEN,
66 Self::EncIpv4Src(_) | Self::EncIpv4Dst(_) => 4,
67 Self::EncIpv6Src(_) | Self::EncIpv6Dst(_) => 16,
68 Self::EncKeyId(_) => 4,
69 Self::EncDstPort(_) => 2,
70 Self::EncTos(_) | Self::EncTtl(_) => 1,
71 Self::NoCsum(_) => 1,
72 Self::Other(attr) => attr.value_len(),
73 }
74 }
75
76 fn emit_value(&self, buffer: &mut [u8]) {
77 match self {
78 Self::Tm(p) => p.emit(buffer),
79 Self::Parms(p) => p.emit(buffer),
80 Self::EncIpv4Src(ip) | Self::EncIpv4Dst(ip) => {
81 buffer.copy_from_slice(&ip.octets())
82 }
83 Self::EncIpv6Src(ip) | Self::EncIpv6Dst(ip) => {
84 buffer.copy_from_slice(&ip.octets())
85 }
86 Self::EncKeyId(i) => BigEndian::write_u32(buffer, *i),
87 Self::EncDstPort(i) => BigEndian::write_u16(buffer, *i),
88 Self::EncTos(i) => buffer[0] = *i,
89 Self::EncTtl(i) => buffer[0] = *i,
90 Self::NoCsum(i) => buffer[0] = *i as u8,
91 Self::Other(attr) => attr.emit_value(buffer),
92 }
93 }
94 fn kind(&self) -> u16 {
95 match self {
96 Self::Tm(_) => TCA_TUNNEL_KEY_TM,
97 Self::Parms(_) => TCA_TUNNEL_KEY_PARMS,
98 Self::EncIpv4Src(_) => TCA_TUNNEL_KEY_ENC_IPV4_SRC,
99 Self::EncIpv4Dst(_) => TCA_TUNNEL_KEY_ENC_IPV4_DST,
100 Self::EncIpv6Src(_) => TCA_TUNNEL_KEY_ENC_IPV6_SRC,
101 Self::EncIpv6Dst(_) => TCA_TUNNEL_KEY_ENC_IPV6_DST,
102 Self::EncKeyId(_) => TCA_TUNNEL_KEY_ENC_KEY_ID,
103 Self::EncDstPort(_) => TCA_TUNNEL_KEY_ENC_DST_PORT,
104 Self::EncTos(_) => TCA_TUNNEL_KEY_ENC_TOS,
105 Self::EncTtl(_) => TCA_TUNNEL_KEY_ENC_TTL,
106 Self::NoCsum(_) => TCA_TUNNEL_KEY_NO_CSUM,
107 Self::Other(nla) => nla.kind(),
108 }
109 }
110}
111
112impl<'a, T: AsRef<[u8]> + ?Sized> Parseable<NlaBuffer<&'a T>>
113 for TcActionTunnelKeyOption
114{
115 fn parse(buf: &NlaBuffer<&'a T>) -> Result<Self, DecodeError> {
116 let payload = buf.value();
117 Ok(match buf.kind() {
118 TCA_TUNNEL_KEY_TM => {
119 Self::Tm(Tcf::parse(&TcfBuffer::new_checked(payload)?)?)
120 }
121 TCA_TUNNEL_KEY_PARMS => Self::Parms(TcTunnelKey::parse(
122 &TcTunnelKeyBuffer::new_checked(payload)?,
123 )?),
124 TCA_TUNNEL_KEY_ENC_IPV4_SRC => Self::EncIpv4Src(
125 parse_ipv4_addr(payload)
126 .context("failed to parse TCA_TUNNEL_KEY_ENC_IPV4_SRC")?,
127 ),
128 TCA_TUNNEL_KEY_ENC_IPV4_DST => Self::EncIpv4Dst(
129 parse_ipv4_addr(payload)
130 .context("failed to parse TCA_TUNNEL_KEY_ENC_IPV4_DST")?,
131 ),
132 TCA_TUNNEL_KEY_ENC_IPV6_SRC => Self::EncIpv6Src(
133 parse_ipv6_addr(payload)
134 .context("failed to parse TCA_TUNNEL_KEY_ENC_IPV6_SRC")?,
135 ),
136 TCA_TUNNEL_KEY_ENC_IPV6_DST => Self::EncIpv6Dst(
137 parse_ipv6_addr(payload)
138 .context("failed to parse TCA_TUNNEL_KEY_ENC_IPV6_DST")?,
139 ),
140 TCA_TUNNEL_KEY_ENC_KEY_ID => Self::EncKeyId(
141 parse_u32_be(payload)
142 .context("failed to parse TCA_TUNNEL_KEY_ENC_KEY_ID")?,
143 ),
144 TCA_TUNNEL_KEY_ENC_DST_PORT => Self::EncDstPort(
145 parse_u16_be(payload)
146 .context("failed to parse TCA_TUNNEL_KEY_ENC_DST_PORT")?,
147 ),
148 TCA_TUNNEL_KEY_ENC_TOS => Self::EncTos(
149 parse_u8(payload)
150 .context("failed to parse TCA_TUNNEL_KEY_ENC_TOS")?,
151 ),
152 TCA_TUNNEL_KEY_ENC_TTL => Self::EncTtl(
153 parse_u8(payload)
154 .context("failed to parse TCA_TUNNEL_KEY_ENC_TTL")?,
155 ),
156 TCA_TUNNEL_KEY_NO_CSUM => Self::NoCsum(
157 parse_u8(payload)
158 .context("invalid TCA_TUNNEL_KEY_NO_CSUM value")?
159 != 0,
160 ),
161 _ => Self::Other(DefaultNla::parse(buf)?),
162 })
163 }
164}
165
166const TC_TUNNEL_KEY_BUF_LEN: usize = TcActionGeneric::BUF_LEN + 4;
167
168#[derive(Debug, PartialEq, Eq, Clone, Default)]
169pub struct TcTunnelKey {
170 pub generic: TcActionGeneric,
171 pub t_action: i32,
172}
173
174buffer!(TcTunnelKeyBuffer(TC_TUNNEL_KEY_BUF_LEN) {
176 generic: (slice, 0..20),
177 t_action: (i32, 20..24),
178});
179
180impl Emitable for TcTunnelKey {
181 fn buffer_len(&self) -> usize {
182 TC_TUNNEL_KEY_BUF_LEN
183 }
184
185 fn emit(&self, buffer: &mut [u8]) {
186 let mut packet = TcTunnelKeyBuffer::new(buffer);
187 self.generic.emit(packet.generic_mut());
188 packet.set_t_action(self.t_action);
189 }
190}
191
192impl<T: AsRef<[u8]> + ?Sized> Parseable<TcTunnelKeyBuffer<&T>> for TcTunnelKey {
193 fn parse(buf: &TcTunnelKeyBuffer<&T>) -> Result<Self, DecodeError> {
194 Ok(Self {
195 generic: TcActionGeneric::parse(&TcActionGenericBuffer::new(
196 buf.generic(),
197 ))?,
198 t_action: buf.t_action(),
199 })
200 }
201}