From ec28986a866ad707b13439b5dfd71cb2304e2ac3 Mon Sep 17 00:00:00 2001 From: Ryan Goodfellow Date: Tue, 21 May 2024 14:06:07 -0700 Subject: [PATCH 1/2] handle unaligned fields > than 1 byte in setters --- codegen/rust/src/header.rs | 8 ++++--- test/src/lib.rs | 2 ++ test/src/p4/vlan_header.p4 | 43 ++++++++++++++++++++++++++++++++++++++ test/src/vlan.rs | 22 +++++++++++++++++++ 4 files changed, 72 insertions(+), 3 deletions(-) create mode 100644 test/src/p4/vlan_header.p4 create mode 100644 test/src/vlan.rs diff --git a/codegen/rust/src/header.rs b/codegen/rust/src/header.rs index 0bbe3c99..448de5b0 100644 --- a/codegen/rust/src/header.rs +++ b/codegen/rust/src/header.rs @@ -71,10 +71,12 @@ impl<'a> HeaderGenerator<'a> { // the p4 confused-endian data model. let mut v = b.into_vec(); v.reverse(); - let mut b = BitVec::::from_vec(v); - if (#end-#offset) < 8 { - b.shift_left(#offset % 8); + if ((#end-#offset) % 8) != 0 { + if let Some(x) = v.iter_mut().last() { + *x <<= (#offset % 8); + } } + let mut b = BitVec::::from_vec(v); b.resize(#end-#offset, false); b } diff --git a/test/src/lib.rs b/test/src/lib.rs index 06e918ea..253295cd 100644 --- a/test/src/lib.rs +++ b/test/src/lib.rs @@ -20,6 +20,8 @@ mod mac_rewrite; mod range; #[cfg(test)] mod table_in_egress_and_ingress; +#[cfg(test)] +mod vlan; pub mod data; pub mod packet; diff --git a/test/src/p4/vlan_header.p4 b/test/src/p4/vlan_header.p4 new file mode 100644 index 00000000..8f2fc408 --- /dev/null +++ b/test/src/p4/vlan_header.p4 @@ -0,0 +1,43 @@ +header ethernet_h { + bit<48> dst; + bit<48> src; + bit<16> ether_type; +} + +header vlan_h { + bit<3> pcp; + bit<1> dei; + bit<12> vid; + bit<16> ether_type; +} + +header sidecar_h { + bit<8> sc_code; + bit<8> sc_pad; + bit<16> sc_ingress; + bit<16> sc_egress; + bit<16> sc_ether_type; + bit<128> sc_payload; +} + +header ipv4_h { + bit<4> version; + bit<4> ihl; + bit<8> diffserv; + bit<16> total_len; + bit<16> identification; + bit<3> flags; + bit<13> frag_offset; + bit<8> ttl; + bit<8> protocol; + bit<16> hdr_checksum; + bit<32> src; + bit<32> dst; +} + +struct headers_t { + ethernet_h ethernet; + vlan_h vlan; + sidecar_h sidecar; + ipv4_h ipv4; +} diff --git a/test/src/vlan.rs b/test/src/vlan.rs new file mode 100644 index 00000000..b804b9fc --- /dev/null +++ b/test/src/vlan.rs @@ -0,0 +1,22 @@ +p4_macro::use_p4!("test/src/p4/vlan_header.p4"); + +#[test] +fn test_vlan_parse() -> anyhow::Result<()> { + let mut data = [0u8; 256]; + 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 mut data = [0u8; 256]; + 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); + + Ok(()) +} From 83ffa784062956241c0faac086dba4fc6d8c91b8 Mon Sep 17 00:00:00 2001 From: Ryan Goodfellow Date: Tue, 21 May 2024 14:14:32 -0700 Subject: [PATCH 2/2] pin toolchain --- rust-toolchain.toml | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 rust-toolchain.toml diff --git a/rust-toolchain.toml b/rust-toolchain.toml new file mode 100644 index 00000000..2fe891cf --- /dev/null +++ b/rust-toolchain.toml @@ -0,0 +1,3 @@ +[toolchain] +channel = "1.77.0" +profile = "default"