sidecar_lite/
lib.rs

1// Copyright 2026 Oxide Computer Company
2
3#![allow(clippy::too_many_arguments)]
4
5p4_macro::use_p4!(p4 = "test/src/p4/sidecar-lite.p4", pipeline_name = "main");
6
7#[cfg(test)]
8mod tests {
9    use super::*;
10    use p4rs::{packet_in, Pipeline};
11
12    fn v6_packet() -> [u8; 62] {
13        let mut buf = [0u8; 62];
14        buf[..6].copy_from_slice(&[0x02, 0, 0, 0, 0, 2]);
15        buf[6..12].copy_from_slice(&[0x02, 0, 0, 0, 0, 1]);
16        buf[12..14].copy_from_slice(&0x86ddu16.to_be_bytes());
17        buf[14] = 0x60;
18        buf[18..20].copy_from_slice(&8u16.to_be_bytes());
19        buf[20] = 59;
20        buf[21] = 64;
21        buf[22..38].copy_from_slice(&[0xfd; 16]);
22        buf[38..54].copy_from_slice(&[0xfe; 16]);
23        buf
24    }
25
26    #[test]
27    fn routing_miss_drops() {
28        let mut pipeline = main_pipeline::new(4);
29        let buf = v6_packet();
30        let mut pkt = packet_in::new(&buf);
31        let out = pipeline.process_packet(0, &mut pkt);
32        let ports: Vec<u16> = out.iter().map(|(_, p)| *p).collect();
33        assert_eq!(ports, Vec::<u16>::new(), "routing miss must drop");
34    }
35
36    #[test]
37    fn mcast_group_replicates_to_bitmap_ports() {
38        let mut pipeline = main_pipeline::new(4);
39
40        let group: std::net::Ipv6Addr = "ff0e::1".parse().unwrap();
41        let bitmap: u128 = (1 << 1) | (1 << 2) | (1 << 3);
42        pipeline.add_ingress_mcast_mcast_replication_v6_entry(
43            "set_port_bitmap",
44            &u128::from(group).to_le_bytes(),
45            &bitmap.to_le_bytes(),
46            0,
47        );
48
49        let mut buf = v6_packet();
50        buf[..6].copy_from_slice(&[0x33, 0x33, 0x00, 0x00, 0x00, 0x01]);
51        buf[38..54].copy_from_slice(&group.octets());
52
53        let mut pkt = packet_in::new(&buf);
54        let packet_ports: Vec<u16> = pipeline
55            .process_packet(1, &mut pkt)
56            .iter()
57            .map(|(_, port)| *port)
58            .collect();
59
60        let mut pkt = packet_in::new(&buf);
61        let header_ports: Vec<u16> = pipeline
62            .process_packet_headers(1, &mut pkt)
63            .iter()
64            .map(|(_, port)| *port)
65            .collect();
66
67        assert_eq!(packet_ports, [2, 3], "packet");
68        assert_eq!(header_ports, [2, 3], "headers");
69    }
70}