Skip to content

Commit 35012a2

Browse files
committed
pping: Add errors to global counters
Add counters for runtime errors in the BPF programs to the global counters. Specifically, add counters for failing to create entries in the packet-timestamp, flow-state and aggregation-subnet maps. The counters can easily be extended to include other errors in the future. Output any non-zero counters at in an errors section at the end of the global-counters report. Example standard entry (linebreaks not part of actual output): 13:53:40.450555237: TCP=(pkts=110983, bytes=899455326), ICMP=(pkts=16, bytes=1568), ECN=(Not-ECT=110999), errors=(store-packet-ts=210, create-flow-state=8, create-agg-subnet-state=110999) Example JSON entry: { "timestamp": 1698235250698609700, "protocol_counters": { "TCP": { "packets": 111736, "bytes": 898999024 }, "ICMP": { "packets": 20, "bytes": 1960 } }, "ecn_counters": { "no_ECT": 111756 }, "errors": { "store_packet_ts": 165, "create_flow_state": 10, "create_agg_subnet_state": 111756 } } Signed-off-by: Simon Sundberg <simon.sundberg@kau.se>
1 parent 0707ac0 commit 35012a2

File tree

3 files changed

+107
-2
lines changed

3 files changed

+107
-2
lines changed

pping/pping.c

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1149,6 +1149,12 @@ static bool ecncounters_empty(const struct ecn_counters *counters)
11491149
return memcmp(counters, &empty, sizeof(empty)) == 0;
11501150
}
11511151

1152+
static bool pping_errors_empty(const struct pping_error_counters *errors)
1153+
{
1154+
static const struct pping_error_counters empty = { 0 };
1155+
1156+
return memcmp(errors, &empty, sizeof(empty)) == 0;
1157+
}
11521158

11531159
static void print_counter_standard(FILE *stream, const char *name, __u64 val,
11541160
bool *first)
@@ -1197,6 +1203,22 @@ static void print_ecncounters_standard(FILE *stream,
11971203
fprintf(stream, ")");
11981204
}
11991205

1206+
static void
1207+
print_ppingerrors_standard(FILE *stream,
1208+
const struct pping_error_counters *errors)
1209+
{
1210+
bool first = true;
1211+
1212+
fprintf(stream, "errors=(");
1213+
print_counter_standard(stream, "store-packet-ts", errors->pktts_store,
1214+
&first);
1215+
print_counter_standard(stream, "create-flow-state", errors->flow_create,
1216+
&first);
1217+
print_counter_standard(stream, "create-agg-subnet-state",
1218+
errors->agg_subnet_create, &first);
1219+
fprintf(stream, ")");
1220+
}
1221+
12001222
static void
12011223
print_globalcounters_standard(FILE *stream, __u64 t_monotonic,
12021224
const struct global_counters *counters)
@@ -1236,6 +1258,11 @@ print_globalcounters_standard(FILE *stream, __u64 t_monotonic,
12361258
print_ecncounters_standard(stream, &counters->ecn);
12371259
}
12381260

1261+
if (!pping_errors_empty(&counters->err)) {
1262+
fprintf(stream, ", ");
1263+
print_ppingerrors_standard(stream, &counters->err);
1264+
}
1265+
12391266
fprintf(stream, "\n");
12401267
}
12411268

@@ -1271,6 +1298,17 @@ static void print_ecncounters_json(json_writer_t *jctx,
12711298
jsonw_end_object(jctx);
12721299
}
12731300

1301+
static void print_ppingerrors_json(json_writer_t *jctx,
1302+
const struct pping_error_counters *errors)
1303+
{
1304+
jsonw_start_object(jctx);
1305+
print_counter_json(jctx, "store_packet_ts", errors->pktts_store);
1306+
print_counter_json(jctx, "create_flow_state", errors->flow_create);
1307+
print_counter_json(jctx, "create_agg_subnet_state",
1308+
errors->agg_subnet_create);
1309+
jsonw_end_object(jctx);
1310+
}
1311+
12741312
static void print_globalcounters_json(json_writer_t *jctx, __u64 t_monotonic,
12751313
const struct global_counters *counters)
12761314
{
@@ -1309,6 +1347,9 @@ static void print_globalcounters_json(json_writer_t *jctx, __u64 t_monotonic,
13091347
jsonw_name(jctx, "ecn_counters");
13101348
print_ecncounters_json(jctx, &counters->ecn);
13111349

1350+
jsonw_name(jctx, "errors");
1351+
print_ppingerrors_json(jctx, &counters->err);
1352+
13121353
jsonw_end_object(jctx);
13131354
}
13141355

@@ -1332,6 +1373,14 @@ static void update_ecncounters(struct ecn_counters *to,
13321373
to->ce += from->ce;
13331374
}
13341375

1376+
static void update_pping_errors(struct pping_error_counters *to,
1377+
const struct pping_error_counters *from)
1378+
{
1379+
to->pktts_store += from->pktts_store;
1380+
to->flow_create += from->flow_create;
1381+
to->agg_subnet_create += from->agg_subnet_create;
1382+
}
1383+
13351384
static void update_globalcounters(struct global_counters *to,
13361385
const struct global_counters *from)
13371386
{
@@ -1353,6 +1402,7 @@ static void update_globalcounters(struct global_counters *to,
13531402
}
13541403

13551404
update_ecncounters(&to->ecn, &from->ecn);
1405+
update_pping_errors(&to->err, &from->err);
13561406
}
13571407

13581408
static void merge_percpu_globalcounters(struct global_counters *merged,
@@ -1378,6 +1428,16 @@ static void diff_ecncounters(struct ecn_counters *diff,
13781428
diff->ce = next->ce - prev->ce;
13791429
}
13801430

1431+
static void diff_pping_errors(struct pping_error_counters *diff,
1432+
const struct pping_error_counters *prev,
1433+
const struct pping_error_counters *next)
1434+
{
1435+
diff->pktts_store = next->pktts_store - prev->pktts_store;
1436+
diff->flow_create = next->flow_create - prev->flow_create;
1437+
diff->agg_subnet_create =
1438+
next->agg_subnet_create - prev->agg_subnet_create;
1439+
}
1440+
13811441
static void diff_globalcounters(struct global_counters *diff,
13821442
const struct global_counters *prev,
13831443
const struct global_counters *next)
@@ -1401,6 +1461,7 @@ static void diff_globalcounters(struct global_counters *diff,
14011461
}
14021462

14031463
diff_ecncounters(&diff->ecn, &prev->ecn, &next->ecn);
1464+
diff_pping_errors(&diff->err, &prev->err, &next->err);
14041465
}
14051466

14061467
static int report_globalcounters(struct output_context *out_ctx,

pping/pping.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,12 @@ enum __attribute__((__packed__)) connection_state {
8383
CONNECTION_STATE_CLOSED
8484
};
8585

86+
enum pping_error {
87+
PPING_ERR_PKTTS_STORE,
88+
PPING_ERR_FLOW_CREATE,
89+
PPING_ERR_AGGSUBNET_CREATE
90+
};
91+
8692
struct bpf_config {
8793
__u64 rate_limit;
8894
fixpoint64 rtt_rate;
@@ -272,8 +278,15 @@ struct ecn_counters {
272278
__u64 ce;
273279
};
274280

281+
struct pping_error_counters {
282+
__u64 pktts_store;
283+
__u64 flow_create;
284+
__u64 agg_subnet_create;
285+
};
286+
275287
struct global_counters {
276288
struct ecn_counters ecn;
289+
struct pping_error_counters err;
277290
__u64 nonip_pkts;
278291
__u64 nonip_bytes;
279292
__u64 tcp_pkts;

pping/pping_kern.c

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -321,6 +321,31 @@ get_dualflow_key_from_packet(struct packet_info *p_info)
321321
&p_info->reply_pid.flow;
322322
}
323323

324+
static void update_pping_error(enum pping_error err)
325+
{
326+
if (!config.agg_rtts)
327+
return;
328+
329+
struct global_counters *counters;
330+
__u32 key = 0;
331+
332+
counters = bpf_map_lookup_elem(&map_global_counters, &key);
333+
if (!counters)
334+
return;
335+
336+
switch (err) {
337+
case PPING_ERR_PKTTS_STORE:
338+
counters->err.pktts_store++;
339+
break;
340+
case PPING_ERR_FLOW_CREATE:
341+
counters->err.flow_create++;
342+
break;
343+
case PPING_ERR_AGGSUBNET_CREATE:
344+
counters->err.agg_subnet_create++;
345+
break;
346+
}
347+
}
348+
324349
static void update_ecn_counters(struct ecn_counters *counters, __u8 ecn)
325350
{
326351
switch (ecn) {
@@ -929,6 +954,7 @@ create_dualflow_state(void *ctx, struct packet_info *p_info)
929954

930955
if (bpf_map_update_elem(&flow_state, key, &new_state, BPF_NOEXIST) !=
931956
0) {
957+
update_pping_error(PPING_ERR_FLOW_CREATE);
932958
send_map_full_event(ctx, p_info, PPING_MAP_FLOWSTATE);
933959
return NULL;
934960
}
@@ -1123,6 +1149,9 @@ lookup_or_create_aggregation_stats(struct in6_addr *ip, __u8 ipv, bool create)
11231149
BPF_NOEXIST);
11241150
// Cannot create new entry, switch to backup entry
11251151
if (!create || (err && err != -EEXIST)) {
1152+
if (create)
1153+
update_pping_error(PPING_ERR_AGGSUBNET_CREATE);
1154+
11261155
if (ipv == AF_INET)
11271156
key.v4 = IPV4_BACKUP_KEY;
11281157
else
@@ -1184,10 +1213,12 @@ static void pping_timestamp_packet(struct flow_state *f_state, void *ctx,
11841213
f_state->last_timestamp = p_info->time;
11851214

11861215
if (bpf_map_update_elem(&packet_ts, &p_info->pid, &p_info->time,
1187-
BPF_NOEXIST) == 0)
1216+
BPF_NOEXIST) == 0) {
11881217
__sync_fetch_and_add(&f_state->outstanding_timestamps, 1);
1189-
else
1218+
} else {
1219+
update_pping_error(PPING_ERR_PKTTS_STORE);
11901220
send_map_full_event(ctx, p_info, PPING_MAP_PACKETTS);
1221+
}
11911222
}
11921223

11931224
/*

0 commit comments

Comments
 (0)