From 227fd15b965bdf5b47724df57eeaf6935587fdd9 Mon Sep 17 00:00:00 2001 From: Ryan Goodfellow Date: Tue, 21 May 2024 21:29:16 -0700 Subject: [PATCH] fix deparse for non-aligned fields > 8 bits (#49) --- codegen/rust/src/header.rs | 19 +++++++------------ test/src/vlan.rs | 10 ++++++++-- 2 files changed, 15 insertions(+), 14 deletions(-) diff --git a/codegen/rust/src/header.rs b/codegen/rust/src/header.rs index 448de5b0..b5b1b84d 100644 --- a/codegen/rust/src/header.rs +++ b/codegen/rust/src/header.rs @@ -85,21 +85,16 @@ impl<'a> HeaderGenerator<'a> { // NOTE this barfing and then unbarfing a vec is to handle // the p4 confused-endian data model. let mut v = self.#name.clone().into_vec(); + if ((#end-#offset) % 8) != 0 { + if let Some(x) = v.iter_mut().last() { + *x >>= ((#end - #offset) % 8); + } + } v.reverse(); let n = (#end-#offset); let m = n%8; - if (n > 8) && m != 0 { - let mut b = BitVec::::from_vec(v); - if b.len() > m { - x[#offset..#end] |= &b[m..]; - } else { - x[#offset..#end] |= &b; - } - } else { - let mut b = BitVec::::from_vec(v); - b.resize(#end-#offset, false); - x[#offset..#end] |= &b; - } + let mut b = BitVec::::from_vec(v); + x[#offset..#end] |= &b[m..]; }); checksum_statements.push(quote! { diff --git a/test/src/vlan.rs b/test/src/vlan.rs index b804b9fc..8e42e867 100644 --- a/test/src/vlan.rs +++ b/test/src/vlan.rs @@ -2,21 +2,27 @@ p4_macro::use_p4!("test/src/p4/vlan_header.p4"); #[test] fn test_vlan_parse() -> anyhow::Result<()> { - let mut data = [0u8; 256]; + let mut data = [0u8; 4]; data[0] = 0x0; data[1] = 0x47; let mut pkt = vlan_h::new(); pkt.set(&data).unwrap(); let vid: u16 = pkt.vid.to_owned().load_le(); assert_eq!(vid, 0x47); + let bv = pkt.to_bitvec(); + let readback = bv.into_vec(); + assert_eq!(data.to_vec(), readback); - let mut data = [0u8; 256]; + let mut data = [0u8; 4]; data[0] = 0x77; data[1] = 0x47; let mut pkt = vlan_h::new(); pkt.set(&data).unwrap(); let vid: u16 = pkt.vid.to_owned().load_le(); assert_eq!(vid, 0x747); + let bv = pkt.to_bitvec(); + let readback = bv.into_vec(); + assert_eq!(data.to_vec(), readback); Ok(()) }