netlink_packet_route/tc/actions/
nat.rs
1use std::net::Ipv4Addr;
7
8use netlink_packet_utils::nla::{DefaultNla, Nla, NlaBuffer};
9use netlink_packet_utils::traits::{Emitable, Parseable};
10use netlink_packet_utils::DecodeError;
11
12use super::nat_flag::TcNatFlags;
13use super::{TcActionGeneric, TcActionGenericBuffer};
14
15const TCA_NAT_PARMS: u16 = 1;
16const TCA_NAT_TM: u16 = 2;
17
18#[derive(Debug, PartialEq, Eq, Clone)]
20#[non_exhaustive]
21pub struct TcActionNat {}
22
23impl TcActionNat {
24 pub(crate) const KIND: &'static str = "nat";
25}
26
27#[derive(Debug, PartialEq, Eq, Clone)]
29#[non_exhaustive]
30pub enum TcActionNatOption {
31 Tm(Vec<u8>),
33 Parms(TcNat),
35 Other(DefaultNla),
37}
38
39impl Nla for TcActionNatOption {
40 fn value_len(&self) -> usize {
41 match self {
42 Self::Tm(bytes) => bytes.len(),
43 Self::Parms(v) => v.buffer_len(),
44 Self::Other(attr) => attr.value_len(),
45 }
46 }
47
48 fn emit_value(&self, buffer: &mut [u8]) {
49 match self {
50 Self::Tm(bytes) => buffer.copy_from_slice(bytes.as_slice()),
51 Self::Parms(p) => p.emit(buffer),
52 Self::Other(attr) => attr.emit_value(buffer),
53 }
54 }
55 fn kind(&self) -> u16 {
56 match self {
57 Self::Tm(_) => TCA_NAT_TM,
58 Self::Parms(_) => TCA_NAT_PARMS,
59 Self::Other(nla) => nla.kind(),
60 }
61 }
62}
63
64impl<'a, T: AsRef<[u8]> + ?Sized> Parseable<NlaBuffer<&'a T>> for TcActionNatOption {
65 type Error = DecodeError;
66 fn parse(buf: &NlaBuffer<&'a T>) -> Result<Self, DecodeError> {
67 let payload = buf.value();
68 Ok(match buf.kind() {
69 TCA_NAT_TM => Self::Tm(payload.to_vec()),
70 TCA_NAT_PARMS => Self::Parms(TcNat::parse(&TcNatBuffer::new_checked(payload)?)?),
71 _ => Self::Other(DefaultNla::parse(buf)?),
72 })
73 }
74}
75
76const TC_NAT_BUF_LEN: usize = TcActionGeneric::BUF_LEN + 16;
77
78#[derive(Debug, PartialEq, Eq, Clone)]
80#[non_exhaustive]
81pub struct TcNat {
82 pub generic: TcActionGeneric,
84 pub old_addr: Ipv4Addr,
86 pub new_addr: Ipv4Addr,
88 pub mask: Ipv4Addr,
90 pub flags: TcNatFlags,
92}
93
94impl Default for TcNat {
95 fn default() -> Self {
96 Self {
97 generic: TcActionGeneric::default(),
98 old_addr: Ipv4Addr::UNSPECIFIED,
99 new_addr: Ipv4Addr::UNSPECIFIED,
100 mask: Ipv4Addr::UNSPECIFIED,
101 flags: TcNatFlags::empty(),
102 }
103 }
104}
105
106buffer!(TcNatBuffer(TC_NAT_BUF_LEN) {
107 generic: (slice, 0..TcActionGeneric::BUF_LEN),
108 old_addr: (slice, TcActionGeneric::BUF_LEN..(TcActionGeneric::BUF_LEN+4)),
109 new_addr: (slice, (TcActionGeneric::BUF_LEN+4)..(TcActionGeneric::BUF_LEN+8)),
110 mask: (slice, (TcActionGeneric::BUF_LEN+8)..(TcActionGeneric::BUF_LEN+12)),
111 flags: (u32, (TcActionGeneric::BUF_LEN+12)..TC_NAT_BUF_LEN),
112});
113
114impl Emitable for TcNat {
115 fn buffer_len(&self) -> usize {
116 TC_NAT_BUF_LEN
117 }
118
119 fn emit(&self, buffer: &mut [u8]) {
120 let mut packet = TcNatBuffer::new(buffer);
121 self.generic.emit(packet.generic_mut());
122 packet.old_addr_mut().copy_from_slice(&self.old_addr.octets());
123 packet.new_addr_mut().copy_from_slice(&self.new_addr.octets());
124 packet.mask_mut().copy_from_slice(&self.mask.octets());
125 packet.set_flags(self.flags.bits());
126 }
127}
128
129impl<'a, T: AsRef<[u8]> + ?Sized> Parseable<TcNatBuffer<&'a T>> for TcNat {
130 type Error = DecodeError;
131 fn parse(buf: &TcNatBuffer<&T>) -> Result<Self, DecodeError> {
132 Ok(Self {
133 generic: TcActionGeneric::parse(&TcActionGenericBuffer::new(buf.generic()))?,
134 old_addr: parse_ipv4(buf.old_addr())?,
135 new_addr: parse_ipv4(buf.new_addr())?,
136 mask: parse_ipv4(buf.mask())?,
137 flags: TcNatFlags::from_bits_retain(buf.flags()),
138 })
139 }
140}
141
142fn parse_ipv4(data: &[u8]) -> Result<Ipv4Addr, DecodeError> {
143 if data.len() != 4 {
144 Err(DecodeError::InvalidIPAddress)
145 } else {
146 Ok(Ipv4Addr::new(data[0], data[1], data[2], data[3]))
147 }
148}