1use core::mem;
2
3#[repr(C, packed)]
8#[derive(Debug, Copy, Clone)]
9#[cfg_attr(feature = "serde", derive(::serde::Serialize, ::serde::Deserialize))]
10pub struct Mpls {
11 pub lbl_tc_s: [u8; 3],
14 pub ttl: u8,
16}
17
18impl Mpls {
19 pub const LEN: usize = mem::size_of::<Mpls>();
20
21 #[inline]
23 pub fn label(&self) -> u32 {
24 let upper_bits = (self.lbl_tc_s[0] as u32) << 12;
25 let middle_bits = (self.lbl_tc_s[1] as u32) << 4;
26 let lower_bits = ((self.lbl_tc_s[2] & 0xF0) >> 4) as u32;
27 upper_bits | middle_bits | lower_bits
28 }
29
30 #[inline]
33 pub fn set_label(&mut self, label: u32) {
34 self.lbl_tc_s[0] = ((label >> 12) & 0xFF) as u8;
35 self.lbl_tc_s[1] = ((label >> 4) & 0xFF) as u8;
36
37 let preserved_bits = self.lbl_tc_s[2] & 0x0F;
39 self.lbl_tc_s[2] = ((label & 0x0F) << 4) as u8 | preserved_bits;
40 }
41
42 #[inline]
45 pub fn tc(&self) -> u8 {
46 (self.lbl_tc_s[2] & 0xE) >> 1
47 }
48
49 #[inline]
53 pub fn set_tc(&mut self, tc_value: u8) {
54 let preserved_bits = self.lbl_tc_s[2] & 0xF1;
55 self.lbl_tc_s[2] = preserved_bits | ((tc_value & 0x07) << 1);
56 }
57
58 #[inline]
61 pub fn s(&self) -> u8 {
62 self.lbl_tc_s[2] & 0x01
63 }
64
65 #[inline]
69 pub fn set_s(&mut self, s_value: u8) {
70 let preserved_bits = self.lbl_tc_s[2] & 0xFE;
71 self.lbl_tc_s[2] = preserved_bits | (s_value & 0x01);
72 }
73
74 #[inline]
76 pub fn ttl(&self) -> u8 {
77 self.ttl
78 }
79
80 #[inline]
83 pub fn set_ttl(&mut self, ttl_value: u8) {
84 self.ttl = ttl_value;
85 }
86}
87
88#[cfg(test)]
89mod tests {
90 use super::*; unsafe fn mpls_from_bytes(bytes: &[u8; Mpls::LEN]) -> &Mpls {
93 &*(bytes.as_ptr() as *const Mpls)
94 }
95
96 unsafe fn mpls_from_bytes_mut(bytes: &mut [u8; Mpls::LEN]) -> &mut Mpls {
97 &mut *(bytes.as_mut_ptr() as *mut Mpls)
98 }
99
100 #[test]
101 fn test_mpls_getters() {
102 let mpls_bytes: [u8; Mpls::LEN] = [0xAB, 0xCD, 0xEB, 0x40];
107 let mpls_header = unsafe { mpls_from_bytes(&mpls_bytes) };
108
109 assert_eq!(mpls_header.label(), 0xABCDE);
110 assert_eq!(mpls_header.tc(), 0x05); assert_eq!(mpls_header.s(), 0x01);
112 assert_eq!(mpls_header.ttl(), 0x40);
113 }
114
115 #[test]
116 fn test_mpls_set_label() {
117 let mut mpls_bytes: [u8; Mpls::LEN] = [0x00, 0x00, 0x00, 0x00];
118 let mpls_header = unsafe { mpls_from_bytes_mut(&mut mpls_bytes) };
119
120 mpls_header.set_label(0x12345);
121 assert_eq!(mpls_header.label(), 0x12345);
126 assert_eq!(mpls_bytes, [0x12, 0x34, 0x50, 0x00]);
127
128 mpls_bytes = [0xFF, 0xFF, 0x0F, 0xFF];
130 let mpls_header2 = unsafe { mpls_from_bytes_mut(&mut mpls_bytes) };
131 mpls_header2.set_label(0xABCDE);
132 assert_eq!(mpls_header2.label(), 0xABCDE);
137 assert_eq!(mpls_header2.tc(), 0x07); assert_eq!(mpls_header2.s(), 0x01); assert_eq!(mpls_bytes, [0xAB, 0xCD, 0xEF, 0xFF]);
140 }
141
142 #[test]
143 fn test_mpls_set_tc() {
144 let mut mpls_bytes: [u8; Mpls::LEN] = [0x00, 0x00, 0xA5, 0x00];
145 let mpls_header = unsafe { mpls_from_bytes_mut(&mut mpls_bytes) };
146
147 mpls_header.set_tc(0x06);
148 assert_eq!(mpls_header.tc(), 0x06);
149 assert_eq!(((mpls_bytes[2] & 0xF0) >> 4), 0x0A);
150 assert_eq!((mpls_bytes[2] & 0x01), 0x01);
151 assert_eq!(mpls_bytes, [0x00, 0x00, 0xAD, 0x00]);
152 }
153
154 #[test]
155 fn test_mpls_set_s() {
156 let mut mpls_bytes: [u8; Mpls::LEN] = [0x00, 0x00, 0xA6, 0x00];
157 let mpls_header = unsafe { mpls_from_bytes_mut(&mut mpls_bytes) };
158
159 mpls_header.set_s(0x01);
160 assert_eq!(mpls_header.s(), 0x01);
161 assert_eq!(((mpls_bytes[2] & 0xF0) >> 4), 0x0A); assert_eq!(((mpls_bytes[2] & 0x0E) >> 1), 0x03); assert_eq!(mpls_bytes, [0x00, 0x00, 0xA7, 0x00]);
164 }
165
166 #[test]
167 fn test_mpls_set_ttl() {
168 let mut mpls_bytes: [u8; Mpls::LEN] = [0x12, 0x34, 0x56, 0x00];
169 let mpls_header = unsafe { mpls_from_bytes_mut(&mut mpls_bytes) };
170
171 mpls_header.set_ttl(0xFF);
172 assert_eq!(mpls_header.ttl(), 0xFF);
173 assert_eq!(mpls_bytes, [0x12, 0x34, 0x56, 0xFF]);
174 }
175}