From 17a3c903ce4f3fb6488e261d649a7d51318f2961 Mon Sep 17 00:00:00 2001 From: Vojtech Vilimek Date: Tue, 19 Jul 2022 10:21:43 +0200 Subject: [PATCH] TMP: compiles and run (doesn't read max generation) --- nest/protocol.h | 1 + proto/stats/config.Y | 28 +++++++++-- proto/stats/stats.c | 115 ++++++++++++++++++++++++++++++++++--------- proto/stats/stats.h | 16 +++++- 4 files changed, 132 insertions(+), 28 deletions(-) diff --git a/nest/protocol.h b/nest/protocol.h index d4c38b90..a2511eb8 100644 --- a/nest/protocol.h +++ b/nest/protocol.h @@ -443,6 +443,7 @@ struct channel_class { }; extern struct channel_class channel_bgp; +extern struct channel_class channel_stats; struct channel_config { node n; diff --git a/proto/stats/config.Y b/proto/stats/config.Y index e66f18d1..b32ea773 100644 --- a/proto/stats/config.Y +++ b/proto/stats/config.Y @@ -15,7 +15,7 @@ CF_HDR CF_DEFINES /* old: #define PIPE_CFG ((struct pipe_config *) this_proto) */ -#define STATS_CFG ((struct stats_config *) this_proto) +#define STATS_CC ((struct stats_channel_config *) this_channel) CF_DECLS @@ -31,16 +31,36 @@ proto: stats_proto '}' { this_channel = NULL; } ; stats_proto_start: proto_start STATS { this_proto = proto_config_new(&proto_stats, $1); - STATS_CFG->max_generation = 16; } proto_name ; -stats_proto_channel: stats_channel_start channel_opt_list channel_end ; +stats_channel_opt_list: + /* empty */ + | '{' stats_opts '}' + ; + + +channel_max_gen: + MAX GENERATION expr { + if ($3 > 254) cf_error("Max generation must be in range 0..254, got %u", $3); + STATS_CC->max_generation = $3; + } + ; + +stats_opts: + /* empty */ + | stats_opts channel_item ';' + | stats_opts channel_max_gen ';' + ; + +stats_proto_channel: stats_channel_start stats_channel_opt_list channel_end ; +/* stats_proto_channel: stats_channel_start stats_max_gen channel_opt_list channel_end ; */ stats_channel_start: net_type symbol { - $$ = this_channel = channel_config_get(NULL, $2->name, $1, this_proto); + this_channel = channel_config_get(&channel_stats, $2->name, $1, this_proto); + STATS_CC->max_generation = 16; } stats_proto: diff --git a/proto/stats/stats.c b/proto/stats/stats.c index ab0b664a..713b6837 100644 --- a/proto/stats/stats.c +++ b/proto/stats/stats.c @@ -32,21 +32,38 @@ static void stats_rt_notify(struct proto *P, struct channel *src_ch, const net_addr *n, rte *new, const rte *old) { - struct stats_proto *p = (void *) P; - struct stats_config *cf = (void *) P->cf; - log(L_INFO "stats_rf_notify()"); + struct stats_channel *ch = src_ch; + log(L_INFO "stats_rt_notify() %u", ch->max_generation); if (old) { - p->counters[old->generation]--; - log(L_INFO "counter %u decreased", old->generation); + if (old->generation < ch->max_generation) + { + ch->counters[old->generation]--; + log(L_INFO "channel %s counter %u was decreased", src_ch->name, old->generation); + } + else + { + log(L_WARN "Stats: Maximum generation reached in channel %s, route is dropped.", + src_ch->name + ); + } } if (new) { - p->counters[new->generation]++; - log(L_INFO "counter %u increased", new->generation); - } + if (new->generation < ch->max_generation) + { + ch->counters[new->generation]++; + log(L_INFO "channel %s counter %u was increased", src_ch->name, new->generation); + } + else + { + log(L_WARN "Stats: Maximum generation reached in channel %s, route is dropped.", + src_ch->name + ); + } + } } static int @@ -72,6 +89,7 @@ stats_configure_channels(struct proto *P, struct proto_config *CF) { struct stats_proto *p = (void *) P; struct stats_config *cf = (void *) CF; + log(L_INFO "stats_configure_channels()"); struct channel_config *cc; WALK_LIST(cc, CF->channels) @@ -115,9 +133,7 @@ static int stats_start(struct proto *P) { struct stats_proto *p = (struct stats_proto *) P; - log(L_INFO "stats_start() "); - - p->counters = (u32 *) mb_allocz(p->p.pool, 256 * sizeof(u32)); + log(L_INFO "stats_start()"); return PS_UP; } @@ -159,27 +175,49 @@ stats_copy_config(struct proto_config *dest UNUSED, struct proto_config *src UNU /* Just a shallow copy, not many items here */ } +/* NO NEED TO PRINT ANYTHING BEFORE protocols header + static void stats_get_status(struct proto *P, byte *buf) { struct stats_proto *p = (void *) P; + + cli_msg(-1006, " another super informative message "); } +*/ static void stats_show_proto_info(struct proto *P) { struct stats_proto *p = (void *) P; + log(L_INFO "stats_show_proto_info() "); - cli_msg(-1006, " Counters contents "); - for (int i = 0; i < 64; i++) + u32 *a = mb_alloc(p->p.pool, 256 * sizeof(u32)); + + struct stats_channel *sc; + WALK_LIST(sc, p->p.channels) { - cli_msg(-1006, "%3u: %10u | %3u: %10u | %3u: %10u | %3u: %10u", - i , *(p->counters + i), - (i + 64 ), *(p->counters + i + 64), - (i + 128), *(p->counters + i + 128), - (i + 192), *(p->counters + i + 192) - ); - } + for (uint i = 0; i < 256; i++) + { + *(a + i) = 0; + } + + u8 len = 0; + for (u8 i = 0; i < sc->max_generation; i++) + if (*(sc->counters + i) != 0) + { + log(L_INFO "found non-zero %u in counter %u", sc->counters[i], i); + *(a + len) = i; + len++; + } + + cli_msg(-1006, " Channel %s counter contents ", sc->c.name); + + for (u8 i = 0; i < len; i ++) + cli_msg(-1006, " %3u: %10u ", i, *(a + i)); + } + + mb_free(a); } void @@ -187,9 +225,42 @@ stats_update_debug(struct proto *P) { struct stats_proto *p = (void *) P; - p->c->debug = p->p.debug; + //p->c->debug = p->p.debug; } +static int +stats_channel_start(struct channel *C) +{ + struct stats_proto *p = (void *) C->proto; + struct stats_channel *c = (void *) C; + log(L_INFO "stats_channel_start() %s", C->name); + + c->pool = p->p.pool; + + c->counters = mb_allocz(c->pool, c->max_generation * sizeof(u32)); + + return 0; +} + +static void +stats_channel_shutdown(struct channel *C) +{ + struct stats_channel *c = (void *) C; + log(L_INFO "stats_channel_shutdown() %s", C->name); + + mb_free(c->counters); + + c->max_generation = 0; + c->counters = NULL; + c->pool = NULL; +} + +struct channel_class channel_stats = { + .channel_size = sizeof(struct stats_channel), + .config_size = sizeof(struct stats_channel_config), + .start = stats_channel_start, + .shutdown = stats_channel_shutdown, +}; struct protocol proto_stats = { .name = "Stats", @@ -201,7 +272,7 @@ struct protocol proto_stats = { .start = stats_start, .reconfigure = stats_reconfigure, .copy_config = stats_copy_config, - .get_status = stats_get_status, + //.get_status = stats_get_status, .show_proto_info = stats_show_proto_info }; diff --git a/proto/stats/stats.h b/proto/stats/stats.h index 552a6d82..12a12c29 100644 --- a/proto/stats/stats.h +++ b/proto/stats/stats.h @@ -10,16 +10,28 @@ #ifndef _BIRD_STATS_H_ #define _BIRD_STATS_H_ +struct stats_channel; + struct stats_config { struct proto_config c; - u8 max_generation; }; struct stats_proto { struct proto p; - struct channel *c; + struct stats_channel *c; struct tbf rl_gen; +}; + +struct stats_channel { + struct channel c; + pool *pool; + u8 max_generation; u32 *counters; }; +struct stats_channel_config { + struct channel_config c; + u8 max_generation; +}; + #endif