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