netlink_packet_route/route/
address.rs
1use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
4
5use netlink_packet_utils::{DecodeError, Emitable};
6
7use crate::ip::{
8 emit_ip_to_buffer, parse_ipv4_addr, parse_ipv6_addr, IPV4_ADDR_LEN, IPV6_ADDR_LEN,
9};
10use crate::route::MplsLabel;
11use crate::AddressFamily;
12
13#[derive(Debug, PartialEq, Eq, Clone)]
14#[non_exhaustive]
15pub enum RouteAddress {
16 Inet(Ipv4Addr),
17 Inet6(Ipv6Addr),
18 Mpls(MplsLabel),
19 Other(Vec<u8>),
20}
21
22impl From<IpAddr> for RouteAddress {
23 fn from(ip: IpAddr) -> Self {
24 match ip {
25 IpAddr::V4(ipv4) => Self::Inet(ipv4),
26 IpAddr::V6(ipv6) => Self::Inet6(ipv6),
27 }
28 }
29}
30
31impl RouteAddress {
32 pub fn parse(address_family: AddressFamily, payload: &[u8]) -> Result<Self, DecodeError> {
33 Ok(match address_family {
34 AddressFamily::Inet => Self::Inet(parse_ipv4_addr(payload)?),
35 AddressFamily::Inet6 => Self::Inet6(parse_ipv6_addr(payload)?),
36 #[cfg(any(target_os = "linux", target_os = "fuchsia"))]
37 AddressFamily::Mpls => Self::Mpls(MplsLabel::parse(payload)?),
38 _ => Self::Other(payload.to_vec()),
39 })
40 }
41}
42
43impl Emitable for RouteAddress {
44 fn buffer_len(&self) -> usize {
45 match self {
46 Self::Inet(_) => IPV4_ADDR_LEN,
47 Self::Inet6(_) => IPV6_ADDR_LEN,
48 Self::Mpls(v) => v.buffer_len(),
49 Self::Other(v) => v.len(),
50 }
51 }
52
53 fn emit(&self, buffer: &mut [u8]) {
54 match self {
55 Self::Inet(v) => emit_ip_to_buffer(&((*v).into()), buffer),
56 Self::Inet6(v) => emit_ip_to_buffer(&((*v).into()), buffer),
57 Self::Mpls(v) => v.emit(buffer),
58 Self::Other(v) => buffer.copy_from_slice(v.as_slice()),
59 }
60 }
61}
62
63impl From<Ipv4Addr> for RouteAddress {
64 fn from(v: Ipv4Addr) -> Self {
65 Self::Inet(v)
66 }
67}
68
69impl From<Ipv6Addr> for RouteAddress {
70 fn from(v: Ipv6Addr) -> Self {
71 Self::Inet6(v)
72 }
73}
74
75impl From<MplsLabel> for RouteAddress {
76 fn from(v: MplsLabel) -> Self {
77 Self::Mpls(v)
78 }
79}