Skip to content

Commit ab1dc8b

Browse files
authored
dendrite#87 all tables should have counters added (#88)
1 parent 974988d commit ab1dc8b

4 files changed

Lines changed: 79 additions & 25 deletions

File tree

dpd/p4/constants.p4

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,9 @@ const bit<8> SVC_COUNTER_FW_FROM_USER = 1;
4545
const bit<8> SVC_COUNTER_V4_PING_REPLY = 2;
4646
const bit<8> SVC_COUNTER_V6_PING_REPLY = 3;
4747
const bit<8> SVC_COUNTER_BAD_PING = 4;
48-
const bit<32> SVC_COUNTER_MAX = 5;
48+
const bit<8> SVC_COUNTER_INBOUND_LL = 5;
49+
const bit<8> SVC_COUNTER_PASS = 6;
50+
const bit<32> SVC_COUNTER_MAX = 7;
4951

5052
/* Encapped Multicast Tags */
5153
const bit<2> MULTICAST_TAG_EXTERNAL = 0;

dpd/p4/sidecar.p4

Lines changed: 28 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -292,7 +292,6 @@ control Services(
292292
// It's not strictly necessary, but we also bump up the TTL to make sure
293293
// the packet makes it all the way back to the sender.
294294
action ping4_reply() {
295-
service_ctr.count(SVC_COUNTER_V4_PING_REPLY);
296295
hdr.ethernet.dst_mac = meta.orig_src_mac;
297296

298297
hdr.ipv4.src_addr = hdr.ipv4.dst_addr;
@@ -305,10 +304,10 @@ control Services(
305304
ig_tm_md.ucast_egress_port = ig_intr_md.ingress_port;
306305

307306
meta.service_routed = true;
307+
service_ctr.count(SVC_COUNTER_V4_PING_REPLY);
308308
}
309309

310310
action ping6_reply() {
311-
service_ctr.count(SVC_COUNTER_V6_PING_REPLY);
312311
hdr.ethernet.dst_mac = meta.orig_src_mac;
313312

314313
bit<128> orig_src = hdr.ipv6.src_addr;
@@ -322,6 +321,7 @@ control Services(
322321
ig_tm_md.ucast_egress_port = ig_intr_md.ingress_port;
323322

324323
meta.service_routed = true;
324+
service_ctr.count(SVC_COUNTER_V6_PING_REPLY);
325325
}
326326

327327
// Send a network service request to a service port. Push on a
@@ -372,6 +372,11 @@ control Services(
372372
ig_tm_md.ucast_egress_port = USER_SPACE_SERVICE_PORT;
373373
meta.is_mcast = true;
374374
meta.is_link_local_mcastv6 = true;
375+
service_ctr.count(SVC_COUNTER_INBOUND_LL);
376+
}
377+
378+
action no_service() {
379+
service_ctr.count(SVC_COUNTER_PASS);
375380
}
376381

377382
table service {
@@ -398,6 +403,7 @@ control Services(
398403
forward_from_userspace;
399404
forward_to_userspace;
400405
mcast_inbound_link_local;
406+
no_service;
401407
}
402408

403409
const entries = {
@@ -417,6 +423,7 @@ control Services(
417423
( 0, false, true, true, _, _, _, _, _, _, _, _, _ ) : mcast_inbound_link_local;
418424
}
419425

426+
default_action = no_service;
420427
const size = 16;
421428
}
422429

@@ -1384,15 +1391,19 @@ control MacRewrite(
13841391
inout sidecar_headers_t hdr,
13851392
in PortId_t port
13861393
) {
1394+
DirectCounter<bit<32>>(CounterType_t.PACKETS_AND_BYTES) ctr;
1395+
13871396
action rewrite(mac_addr_t mac) {
13881397
hdr.ethernet.src_mac = mac;
1398+
ctr.count();
13891399
}
13901400

13911401
table mac_rewrite {
13921402
key = { port: exact ; }
13931403
actions = { rewrite; }
13941404

13951405
const size = 256;
1406+
counters = ctr;
13961407
}
13971408

13981409
apply {
@@ -1409,15 +1420,19 @@ control MulticastMacRewrite(
14091420
inout sidecar_headers_t hdr,
14101421
in PortId_t port
14111422
) {
1423+
DirectCounter<bit<32>>(CounterType_t.PACKETS_AND_BYTES) ctr;
1424+
14121425
action rewrite(mac_addr_t mac) {
14131426
hdr.ethernet.src_mac = mac;
1427+
ctr.count();
14141428
}
14151429

14161430
table mac_rewrite {
14171431
key = { port: exact ; }
14181432
actions = { rewrite; }
14191433

14201434
const size = 256;
1435+
counters = ctr;
14211436
}
14221437

14231438
apply {
@@ -2089,6 +2104,7 @@ control Egress(
20892104
MulticastMacRewrite() mac_rewrite;
20902105
MulticastEgress() mcast_egress;
20912106

2107+
Counter<bit<64>, PortId_t>(512, CounterType_t.PACKETS_AND_BYTES) unicast_ctr;
20922108
Counter<bit<64>, PortId_t>(512, CounterType_t.PACKETS_AND_BYTES) mcast_ctr;
20932109
Counter<bit<64>, PortId_t>(512, CounterType_t.PACKETS_AND_BYTES) link_local_mcast_ctr;
20942110
Counter<bit<64>, PortId_t>(512, CounterType_t.PACKETS_AND_BYTES) external_mcast_ctr;
@@ -2100,12 +2116,12 @@ control Egress(
21002116
// Check multicast egress packets by checking that RID is not 0.
21012117
bool is_egress_rid_mcast = eg_intr_md.egress_rid > 0;
21022118
// We track IPv6 multicast packets separately for counters.
2103-
bool is_ipv6_mcast = false;
2119+
bool is_link_local_ipv6_mcast = false;
21042120
if (hdr.ipv6.isValid()) {
21052121
bit<16> ipv6_prefix = (bit<16>)hdr.ipv6.dst_addr[127:112];
2106-
is_ipv6_mcast = (ipv6_prefix != 16w0xff02);
2122+
is_link_local_ipv6_mcast = (ipv6_prefix == 16w0xff02);
21072123
}
2108-
bool is_mcast = is_egress_rid_mcast || is_ipv6_mcast;
2124+
bool is_mcast = is_egress_rid_mcast || is_link_local_ipv6_mcast;
21092125

21102126
if (is_egress_rid_mcast == true) {
21112127
if (meta.bridge_hdr.ingress_port == eg_intr_md.egress_port) {
@@ -2117,7 +2133,8 @@ control Egress(
21172133
mcast_egress.apply(hdr, meta, eg_intr_md, eg_dprsr_md);
21182134
mac_rewrite.apply(hdr, eg_intr_md.egress_port);
21192135
}
2120-
} else if (eg_intr_md.egress_rid == 0 && eg_intr_md.egress_rid_first == 1) {
2136+
} else if (eg_intr_md.egress_rid == 0 &&
2137+
eg_intr_md.egress_rid_first == 1) {
21212138
// Drop CPU copies (RID=0) to prevent unwanted packets on port 0
21222139
eg_dprsr_md.drop_ctl = 1;
21232140
meta.drop_reason = DROP_MULTICAST_CPU_COPY;
@@ -2130,7 +2147,7 @@ control Egress(
21302147
} else if (is_mcast == true) {
21312148
mcast_ctr.count(eg_intr_md.egress_port);
21322149

2133-
if (is_ipv6_mcast) {
2150+
if (is_link_local_ipv6_mcast) {
21342151
link_local_mcast_ctr.count(eg_intr_md.egress_port);
21352152
} else if (hdr.geneve.isValid()) {
21362153
external_mcast_ctr.count(eg_intr_md.egress_port);
@@ -2139,6 +2156,10 @@ control Egress(
21392156
hdr.geneve_opts.oxg_mcast.mcast_tag == MULTICAST_TAG_UNDERLAY) {
21402157
underlay_mcast_ctr.count(eg_intr_md.egress_port);
21412158
}
2159+
} else {
2160+
# non-multicast packets should bypass the egress
2161+
# pipeline, so we would expect this to be 0.
2162+
unicast_ctr.count(eg_intr_md.egress_port);
21422163
}
21432164
}
21442165
}

dpd/src/counters.rs

Lines changed: 33 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -52,10 +52,16 @@ enum CounterId {
5252
Service,
5353
Ingress,
5454
Egress,
55-
Multicast,
5655
Packet,
5756
DropPort,
5857
DropReason,
58+
EgressDropPort,
59+
EgressDropReason,
60+
Unicast,
61+
Multicast,
62+
MulticastExt,
63+
MulticastLL,
64+
MulticastUL,
5965
}
6066

6167
impl From<CounterId> for u8 {
@@ -78,7 +84,7 @@ struct CounterDescription {
7884
p4_name: &'static str,
7985
}
8086

81-
const COUNTERS: [CounterDescription; 12] = [
87+
const COUNTERS: [CounterDescription; 13] = [
8288
CounterDescription {
8389
id: CounterId::Service,
8490
client_name: "Service",
@@ -110,32 +116,37 @@ const COUNTERS: [CounterDescription; 12] = [
110116
p4_name: "pipe.Ingress.drop_reason_ctr",
111117
},
112118
CounterDescription {
113-
id: CounterId::DropPort,
119+
id: CounterId::EgressDropPort,
114120
client_name: "Egress_Drop_Port",
115121
p4_name: "pipe.Egress.drop_port_ctr",
116122
},
117123
CounterDescription {
118-
id: CounterId::DropReason,
124+
id: CounterId::EgressDropReason,
119125
client_name: "Egress_Drop_Reason",
120126
p4_name: "pipe.Egress.drop_reason_ctr",
121127
},
122128
CounterDescription {
123-
id: CounterId::Multicast,
124-
client_name: "Multicast",
125-
p4_name: "pipe.Egress.mcast_ctr",
129+
id: CounterId::Unicast,
130+
client_name: "Unicast",
131+
p4_name: "pipe.Egress.unicast_ctr",
126132
},
127133
CounterDescription {
128134
id: CounterId::Multicast,
129-
client_name: "Multicast_Link_Local",
130-
p4_name: "pipe.Egress.link_local_mcast_ctr",
135+
client_name: "Multicast",
136+
p4_name: "pipe.Egress.mcast_ctr",
131137
},
132138
CounterDescription {
133-
id: CounterId::Multicast,
139+
id: CounterId::MulticastExt,
134140
client_name: "Multicast_External",
135141
p4_name: "pipe.Egress.external_mcast_ctr",
136142
},
137143
CounterDescription {
138-
id: CounterId::Multicast,
144+
id: CounterId::MulticastLL,
145+
client_name: "Multicast_Link_Local",
146+
p4_name: "pipe.Egress.link_local_mcast_ctr",
147+
},
148+
CounterDescription {
149+
id: CounterId::MulticastUL,
139150
client_name: "Multicast_Underlay",
140151
p4_name: "pipe.Egress.underlay_mcast_ctr",
141152
},
@@ -230,6 +241,8 @@ fn service_label(ctr: u8) -> Option<String> {
230241
2 => "ping_v4_reply".to_string(),
231242
3 => "ping_v6_reply".to_string(),
232243
4 => "bad_ping".to_string(),
244+
5 => "inbound_link_local".to_string(),
245+
6 => "pass".to_string(),
233246
x => format!("unknown service counter {x}"),
234247
};
235248
Some(label)
@@ -397,9 +410,16 @@ pub async fn get_values(
397410
CounterId::Service => service_label(idx.idx as u8),
398411
CounterId::Ingress
399412
| CounterId::Egress
413+
| CounterId::EgressDropPort
400414
| CounterId::DropPort
401-
| CounterId::Multicast => port_label(switch, idx.idx).await,
402-
CounterId::DropReason => reason_label(idx.idx as u8)?,
415+
| CounterId::Unicast
416+
| CounterId::Multicast
417+
| CounterId::MulticastExt
418+
| CounterId::MulticastLL
419+
| CounterId::MulticastUL => port_label(switch, idx.idx).await,
420+
CounterId::DropReason | CounterId::EgressDropReason => {
421+
reason_label(idx.idx as u8)?
422+
}
403423
};
404424

405425
if let Some(key) = key {

dpd/src/table/mod.rs

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -333,6 +333,9 @@ pub fn get_counters(
333333
neighbor_ipv6::counter_fetch(switch, force_sync)
334334
}
335335
TableType::ArpIpv4 => arp_ipv4::counter_fetch(switch, force_sync),
336+
TableType::PortMac => {
337+
MacOps::<port_mac::PortMacTable>::counter_fetch(switch, force_sync)
338+
}
336339
TableType::NatIngressIpv4 => {
337340
nat::ipv4_counter_fetch(switch, force_sync)
338341
}
@@ -369,10 +372,11 @@ pub fn get_counters(
369372
TableType::McastEgressPortMapping => {
370373
mcast::mcast_egress::port_mapping_counter_fetch(switch, force_sync)
371374
}
372-
373-
// There is no counter in the PortMac table, as it duplicates data
374-
// already available in the rmon egress counter.
375-
_ => Err(DpdError::NoSuchTable(name)),
375+
TableType::PortMacMcast => {
376+
MacOps::<mcast::mcast_port_mac::PortMacTable>::counter_fetch(
377+
switch, force_sync,
378+
)
379+
}
376380
}
377381
}
378382

@@ -548,6 +552,13 @@ impl<T: MacTable> MacOps<T> {
548552
s.table_dump::<MacMatchKey, MacAction>(T::table_type())
549553
}
550554

555+
pub fn counter_fetch(
556+
s: &Switch,
557+
force_sync: bool,
558+
) -> DpdResult<Vec<views::TableCounterEntry>> {
559+
s.counter_fetch::<MacMatchKey>(force_sync, T::table_type())
560+
}
561+
551562
/// Remove all entries from the MAC table.
552563
#[cfg_attr(not(feature = "tofino_asic"), allow(dead_code))]
553564
pub fn reset(s: &Switch) -> DpdResult<()> {

0 commit comments

Comments
 (0)