Skip to content

Commit

Permalink
handle unaligned fields > than 1 byte in setters
Browse files Browse the repository at this point in the history
  • Loading branch information
rcgoodfellow committed May 21, 2024
1 parent 526a5bd commit ec28986
Show file tree
Hide file tree
Showing 4 changed files with 72 additions and 3 deletions.
8 changes: 5 additions & 3 deletions codegen/rust/src/header.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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::<u8, Msb0>::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::<u8, Msb0>::from_vec(v);
b.resize(#end-#offset, false);
b
}
Expand Down
2 changes: 2 additions & 0 deletions test/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
43 changes: 43 additions & 0 deletions test/src/p4/vlan_header.p4
Original file line number Diff line number Diff line change
@@ -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;
}
22 changes: 22 additions & 0 deletions test/src/vlan.rs
Original file line number Diff line number Diff line change
@@ -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(())
}

0 comments on commit ec28986

Please sign in to comment.