netlink_packet_route/link/link_info/
hsr.rs1use netlink_packet_core::{
4 emit_u16, emit_u32, parse_mac, parse_u16, parse_u32, parse_u8, DecodeError,
5 DefaultNla, ErrorContext, Nla, NlaBuffer, Parseable,
6};
7
8const IFLA_HSR_PORT1: u16 = 1;
10const IFLA_HSR_PORT2: u16 = 2;
12const IFLA_HSR_MULTICAST_SPEC: u16 = 3;
13const IFLA_HSR_SUPERVISION_ADDR: u16 = 4;
14const IFLA_HSR_SEQ_NR: u16 = 5;
15const IFLA_HSR_VERSION: u16 = 6;
16const IFLA_HSR_PROTOCOL: u16 = 7;
17const IFLA_HSR_INTERLINK: u16 = 8;
18
19#[derive(Debug, PartialEq, Eq, Clone)]
20#[non_exhaustive]
21pub enum InfoHsr {
22 Port1(u32),
23 Port2(u32),
24 Interlink(u32),
25 MulticastSpec(u8),
26 SupervisionAddr([u8; 6]),
27 Version(u8),
28 SeqNr(u16),
29 Protocol(HsrProtocol),
30 Other(DefaultNla),
31}
32
33impl Nla for InfoHsr {
34 fn value_len(&self) -> usize {
35 use self::InfoHsr::*;
36 match self {
37 SupervisionAddr(_) => 6,
38 Port1(_) | Port2(_) | Interlink(_) => 4,
39 SeqNr(_) => 2,
40 MulticastSpec(_) | Version(_) | Protocol(_) => 1,
41 Other(nla) => nla.value_len(),
42 }
43 }
44
45 fn emit_value(&self, buffer: &mut [u8]) {
46 use self::InfoHsr::*;
47 match self {
48 Port1(value) | Port2(value) | Interlink(value) => {
49 emit_u32(buffer, *value).unwrap()
50 }
51 MulticastSpec(value) | Version(value) => buffer[0] = *value,
52 SeqNr(value) => emit_u16(buffer, *value).unwrap(),
53 Protocol(value) => buffer[0] = (*value).into(),
54 SupervisionAddr(ref value) => buffer.copy_from_slice(&value[..]),
55 Other(nla) => nla.emit_value(buffer),
56 }
57 }
58
59 fn kind(&self) -> u16 {
60 use self::InfoHsr::*;
61 match self {
62 Port1(_) => IFLA_HSR_PORT1,
63 Port2(_) => IFLA_HSR_PORT2,
64 Interlink(_) => IFLA_HSR_INTERLINK,
65 MulticastSpec(_) => IFLA_HSR_MULTICAST_SPEC,
66 SupervisionAddr(_) => IFLA_HSR_SUPERVISION_ADDR,
67 SeqNr(_) => IFLA_HSR_SEQ_NR,
68 Version(_) => IFLA_HSR_VERSION,
69 Protocol(_) => IFLA_HSR_PROTOCOL,
70 Other(nla) => nla.kind(),
71 }
72 }
73}
74
75impl<'a, T: AsRef<[u8]> + ?Sized> Parseable<NlaBuffer<&'a T>> for InfoHsr {
76 fn parse(buf: &NlaBuffer<&'a T>) -> Result<Self, DecodeError> {
77 use self::InfoHsr::*;
78 let payload = buf.value();
79 Ok(match buf.kind() {
80 IFLA_HSR_PORT1 => Port1(
81 parse_u32(payload).context("invalid IFLA_HSR_PORT1 value")?,
82 ),
83 IFLA_HSR_PORT2 => Port2(
84 parse_u32(payload).context("invalid IFLA_HSR_PORT2 value")?,
85 ),
86 IFLA_HSR_INTERLINK => Interlink(
87 parse_u32(payload)
88 .context("invalid IFLA_HSR_INTERLINK value")?,
89 ),
90 IFLA_HSR_MULTICAST_SPEC => MulticastSpec(
91 parse_u8(payload)
92 .context("invalid IFLA_HSR_MULTICAST_SPEC value")?,
93 ),
94 IFLA_HSR_SUPERVISION_ADDR => SupervisionAddr(
95 parse_mac(payload)
96 .context("invalid IFLA_HSR_SUPERVISION_ADDR value")?,
97 ),
98 IFLA_HSR_SEQ_NR => SeqNr(
99 parse_u16(payload).context("invalid IFLA_HSR_SEQ_NR value")?,
100 ),
101 IFLA_HSR_VERSION => Version(
102 parse_u8(payload).context("invalid IFLA_HSR_VERSION value")?,
103 ),
104 IFLA_HSR_PROTOCOL => Protocol(
105 parse_u8(payload)
106 .context("invalid IFLA_HSR_PROTOCOL value")?
107 .into(),
108 ),
109 kind => Other(
110 DefaultNla::parse(buf)
111 .context(format!("unknown NLA type {kind}"))?,
112 ),
113 })
114 }
115}
116
117const HSR_PROTOCOL_HSR: u8 = 0;
118const HSR_PROTOCOL_PRP: u8 = 1;
119
120#[derive(Debug, PartialEq, Eq, Clone, Copy)]
121#[non_exhaustive]
122#[repr(u8)]
123pub enum HsrProtocol {
124 Hsr = HSR_PROTOCOL_HSR,
125 Prp = HSR_PROTOCOL_PRP,
126 Other(u8),
127}
128
129impl From<u8> for HsrProtocol {
130 fn from(d: u8) -> Self {
131 match d {
132 HSR_PROTOCOL_HSR => Self::Hsr,
133 HSR_PROTOCOL_PRP => Self::Prp,
134 _ => Self::Other(d),
135 }
136 }
137}
138
139impl From<HsrProtocol> for u8 {
140 fn from(d: HsrProtocol) -> Self {
141 match d {
142 HsrProtocol::Hsr => HSR_PROTOCOL_HSR,
143 HsrProtocol::Prp => HSR_PROTOCOL_PRP,
144 HsrProtocol::Other(value) => value,
145 }
146 }
147}
148
149impl std::fmt::Display for HsrProtocol {
150 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
151 match self {
152 Self::Hsr => write!(f, "hsr"),
153 Self::Prp => write!(f, "prp"),
154 Self::Other(d) => write!(f, "{d}"),
155 }
156 }
157}