Skip to content

Egress (port) counters return 0 even when counters are updated in Tofino Simulator #35

Open
@zeeshanlakhani

Description

@zeeshanlakhani

While all counters are correctly registered in #14, we're not seeing counts increment via the counters API call (in packet tests) for Egress counters:

async fn check_counter_incremented(
    switch: &Switch,
    counter_name: &str,
    baseline: u64,
    expected_increment: u64,
    client_name: Option<&str>,
) -> anyhow::Result<u64> {
    let mut new_value = 0;

    // Poll for the counter value (with timeout)
    for _i in 0..20 {
        std::thread::sleep(std::time::Duration::from_millis(100));
        new_value =
            switch.get_counter(counter_name, client_name).await.unwrap();

        if new_value == baseline + expected_increment {
            return Ok(new_value);
        }
    }

    // Counter didn't increment as expected
    Err(anyhow!(
        "Counter '{}' expected to increase by {} (from {} to {}), but only reached {}",
        counter_name,
        expected_increment,
        baseline,
        baseline + expected_increment,
        new_value
    ))
}
check_counter_incremented(
    switch,
    &port_label_egress1,
    ctr_baseline_egress1,
    1,
    Some("egress"),
)
.await
.unwrap();

However, the same test function works correctly for Ingress port counters. Of note, the simulator logs show that the counter was, indeed, updated:

:04-22 13:08:57.320787: :-:0x3100000000000001:<0,1,3>:Egress : Gateway did provide payload.
:04-22 13:08:57.320797: :-:0x3100000000000001:<0,1,3>:Execute Action: sidecar1745
:04-22 13:08:57.320825: :-:0x3100000000000001:<0,1,3>:Action Results:
:04-22 13:08:57.320834: :-:0x3100000000000001:<0,1,3>: ----- CountFromHashPrimitive -----
:04-22 13:08:57.320842: :-:0x3100000000000001:<0,1,3>: ----- Update counter: Egress.egress_ctr
:04-22 13:08:57.320851: :-:0x3100000000000001:<0,1,3>: VPN : 0 Ram Line : 0 Subword(Including LSBs. Need to right shift based on stats table format) : 0
:04-22 13:08:57.320860: :-:0x3100000000000001:<0,1,3>:Next Table = --END_OF_PIPELINE--
:04-22 13:08:57.320872: :-:0x3100000000000001:<0,1,->:------------ Stage 4 ------------
:04-22 13:08:57.321005: :-:0x3100000000000001:<0,1,4>:Egress : Table tbl_sidecar1742 is not active(inhibited/skipped)

Here's the P4 Egress control. We had not done any work here before (just an empty apply):

control Egress(
	inout sidecar_headers_t hdr,
	inout sidecar_egress_meta_t meta,
	in egress_intrinsic_metadata_t eg_intr_md,
	in egress_intrinsic_metadata_from_parser_t eg_prsr_md,
	inout egress_intrinsic_metadata_for_deparser_t eg_dprsr_md,
	inout egress_intrinsic_metadata_for_output_port_t eg_oport_md
) {

	Counter<bit<64>, PortId_t>(512, CounterType_t.PACKETS_AND_BYTES) egress_ctr;
	Counter<bit<64>, PortId_t>(512, CounterType_t.PACKETS_AND_BYTES) mcast_ctr;
	Counter<bit<32>, PortId_t>(512, CounterType_t.PACKETS) drop_port_ctr;
	Counter<bit<32>, bit<8>>(DROP_REASON_MAX, CounterType_t.PACKETS) drop_reason_ctr;

	apply {
		// Check multicast egress packets by enforcing replication_id usage
		if (eg_intr_md.egress_rid > 0 ||
			(hdr.ipv6.isValid() && (bit<16>)hdr.ipv6.dst_addr[127:112] != 16w0xff02)) {
			mcast_ctr.count(eg_intr_md.egress_port);
        } else if (eg_intr_md.egress_rid == 0 && eg_intr_md.egress_rid_first == 1) {
			// Drop CPU copies (RID=0) to prevent unwanted packets on port 0
			eg_dprsr_md.drop_ctl = 1;
			meta.drop_reason = DROP_MULTICAST_CPU_COPY;
		}

		if (meta.drop_reason != 0) {
			// Handle dropped packets
			drop_port_ctr.count(eg_intr_md.egress_port);
			drop_reason_ctr.count(meta.drop_reason);
		} else {
			egress_ctr.count(eg_intr_md.egress_port);
		}
	}
}

Checklist

  • Test if also a hardware issue

Metadata

Metadata

Assignees

No one assigned

    Labels

    tofino-simulatorTofino-simulator specific issues

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions