From b9baa79b4dc277501f860325da34403b89fb4ee9 Mon Sep 17 00:00:00 2001 From: Zeeshan Lakhani Date: Sat, 7 Nov 2026 01:55:46 +0000 Subject: [PATCH] [codegen, fix] Replace (not insert) table entries with matching keys `HashSet::insert` retained the prev entry, which meant that adding the same key with a new action or new params was a no-op. We now use replace per @rcgoodfellow @ oxidecomputer/dendrite#405. --- codegen/rust/src/pipeline.rs | 4 +++- test/src/mcast.rs | 28 ++++++++++++++++++++++++++++ 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/codegen/rust/src/pipeline.rs b/codegen/rust/src/pipeline.rs index 4bca914e..a73e601e 100644 --- a/codegen/rust/src/pipeline.rs +++ b/codegen/rust/src/pipeline.rs @@ -1000,9 +1000,11 @@ impl<'a> PipelineGenerator<'a> { #(#parameter_refs),* ) }); + // Upserting an entry replaces any previous entry with a + // matching key self.#tname .entries - .insert(p4rs::table::TableEntry::< + .replace(p4rs::table::TableEntry::< #n, std::sync::Arc Result<(), anyhow::Error> { Ok(()) } +#[test] +fn upserting_key_replaces_action_and_params() { + let mut pipeline = main_pipeline::new(4); + let key = 0u16.to_le_bytes(); + + pipeline.add_ingress_bitmap_table_entry( + "set_bitmap", + &key, + &port_bitmap(16, &[1, 2]), + 0, + ); + pipeline.add_ingress_bitmap_table_entry( + "set_bitmap", + &key, + &port_bitmap(16, &[3]), + 0, + ); + assert_egress_ports(&mut pipeline, 0, &[3]); + + pipeline.add_ingress_bitmap_table_entry( + "forward", + &key, + &1u16.to_le_bytes(), + 0, + ); + assert_egress_ports(&mut pipeline, 0, &[1]); +} + fn unicast_mac(port: u16) -> [u8; 6] { let id = 0x20 + port as u8; [0x02, 0x00, id, id, 0x00, 0x02]