From 574b2324275d3292e98a8e329f791eb5c799f7f2 Mon Sep 17 00:00:00 2001 From: "Ondrej Zajicek (work)" Date: Tue, 28 Nov 2017 17:06:10 +0100 Subject: [PATCH] Timers: Fix TBF and some last remains --- conf/conf.c | 6 +++--- lib/birdlib.h | 30 ++++++++---------------------- lib/tbf.c | 31 +++++++++++++++++++------------ lib/timer.h | 4 ++-- nest/proto.c | 2 +- proto/ospf/ospf.h | 2 +- proto/rip/packets.c | 5 ++++- sysdep/linux/netlink.c | 2 +- sysdep/unix/io.c | 2 +- sysdep/unix/log.c | 7 +++---- sysdep/unix/timer.h | 4 ++-- 11 files changed, 45 insertions(+), 50 deletions(-) diff --git a/conf/conf.c b/conf/conf.c index 2b5e9c71..c68ded7f 100644 --- a/conf/conf.c +++ b/conf/conf.c @@ -384,7 +384,7 @@ config_confirm(void) if (config_timer->expires == 0) return CONF_NOTHING; - tm_stop(config_timer); + tm2_stop(config_timer); return CONF_CONFIRM; } @@ -420,7 +420,7 @@ config_undo(void) return CONF_NOTHING; undo_available = 0; - tm_stop(config_timer); + tm2_stop(config_timer); if (configuring) { @@ -468,7 +468,7 @@ config_init(void) config_event = ev_new(&root_pool); config_event->hook = config_done; - config_timer = tm_new(&root_pool); + config_timer = tm2_new(&root_pool); config_timer->hook = config_timeout; } diff --git a/lib/birdlib.h b/lib/birdlib.h index 9a77fc7b..f41cceb5 100644 --- a/lib/birdlib.h +++ b/lib/birdlib.h @@ -69,7 +69,7 @@ static inline int u64_cmp(u64 i1, u64 i2) /* Microsecond time */ typedef s64 btime; -typedef s64 bird_clock_t; +//typedef s64 bird_clock_t; #define S_ * (btime) 1000000 #define MS_ * (btime) 1000 @@ -85,37 +85,23 @@ typedef s64 bird_clock_t; #define NS /1000 #endif +#define TIME_INFINITY ((s64) 0x7fffffffffffffff) + /* Rate limiting */ struct tbf { - bird_clock_t timestamp; /* Last update */ - u16 count; /* Available tokens */ + btime timestamp; /* Last update */ + u64 count; /* Available micro-tokens */ u16 burst; /* Max number of tokens */ - u16 rate; /* Rate of replenishment */ - u16 mark; /* Whether last op was limited */ + u16 rate; /* Rate of replenishment (tokens / sec) */ + u32 drop; /* Number of failed request since last successful */ }; /* Default TBF values for rate limiting log messages */ #define TBF_DEFAULT_LOG_LIMITS { .rate = 1, .burst = 5 } -void tbf_update(struct tbf *f); - -static inline int -tbf_limit(struct tbf *f) -{ - tbf_update(f); - - if (!f->count) - { - f->mark = 1; - return 1; - } - - f->count--; - f->mark = 0; - return 0; -} +int tbf_limit(struct tbf *f); /* Logging and dying */ diff --git a/lib/tbf.c b/lib/tbf.c index c1dafee8..e6e84b4f 100644 --- a/lib/tbf.c +++ b/lib/tbf.c @@ -10,21 +10,28 @@ #include "nest/bird.h" #include "lib/timer.h" -void -tbf_update(struct tbf *f) +int +tbf_limit(struct tbf *f) { - bird_clock_t delta = now - f->timestamp; + btime delta = current_time() - f->timestamp; - if (delta == 0) - return; - - f->timestamp = now; - - if ((0 < delta) && (delta < f->burst)) + if (delta > 0) { - u32 next = f->count + delta * f->rate; - f->count = MIN(next, f->burst); + u64 next = f->count + delta * f->rate; + u64 burst = (u64) f->burst << 20; + f->count = MIN(next, burst); + f->timestamp += delta; + } + + if (f->count < 1000000) + { + f->drop++; + return 1; } else - f->count = f->burst; + { + f->count -= 1000000; + f->drop = 0; + return 0; + } } diff --git a/lib/timer.h b/lib/timer.h index 61a2aa94..250bb3cd 100644 --- a/lib/timer.h +++ b/lib/timer.h @@ -46,8 +46,8 @@ extern struct timeloop main_timeloop; btime current_time(void); btime current_real_time(void); -#define now (current_time() TO_S) -#define now_real (current_real_time() TO_S) +//#define now (current_time() TO_S) +//#define now_real (current_real_time() TO_S) extern btime boot_time; timer2 *tm2_new(pool *p); diff --git a/nest/proto.c b/nest/proto.c index 27c8fded..72f1f94d 100644 --- a/nest/proto.c +++ b/nest/proto.c @@ -1288,7 +1288,7 @@ protos_build(void) #endif proto_pool = rp_new(&root_pool, "Protocols"); - proto_shutdown_timer = tm_new(proto_pool); + proto_shutdown_timer = tm2_new(proto_pool); proto_shutdown_timer->hook = proto_shutdown_loop; } diff --git a/proto/ospf/ospf.h b/proto/ospf/ospf.h index dbc231b6..d4571bf6 100644 --- a/proto/ospf/ospf.h +++ b/proto/ospf/ospf.h @@ -58,7 +58,7 @@ log_rl(&p->log_lsa_tbf, L_REMOTE "%s: " msg, p->p.name, args) #define LOG_LSA2(msg, args...) \ - do { if (! p->log_lsa_tbf.mark) \ + do { if (! p->log_lsa_tbf.drop) \ log(L_REMOTE "%s: " msg, p->p.name, args); } while(0) diff --git a/proto/rip/packets.c b/proto/rip/packets.c index 1518dd3f..4925ca36 100644 --- a/proto/rip/packets.c +++ b/proto/rip/packets.c @@ -189,7 +189,10 @@ rip_update_csn(struct rip_proto *p UNUSED, struct rip_iface *ifa) * have the same CSN. We are using real time, but enforcing monotonicity. */ if (ifa->cf->auth_type == RIP_AUTH_CRYPTO) - ifa->csn = (ifa->csn < (u32) now_real) ? (u32) now_real : ifa->csn + 1; + { + u32 now_real = (u32) (current_real_time() TO_S); + ifa->csn = (ifa->csn < now_real) ? now_real : ifa->csn + 1; + } } static void diff --git a/sysdep/linux/netlink.c b/sysdep/linux/netlink.c index c9d5cdec..6477d18c 100644 --- a/sysdep/linux/netlink.c +++ b/sysdep/linux/netlink.c @@ -151,7 +151,7 @@ nl_open_sock(struct nl_sock *nl) nl->fd = socket(PF_NETLINK, SOCK_RAW, NETLINK_ROUTE); if (nl->fd < 0) die("Unable to open rtnetlink socket: %m"); - nl->seq = now; + nl->seq = (u32) (current_time() TO_S); /* Or perhaps random_u32() ? */ nl->rx_buffer = xmalloc(NL_RX_SIZE); nl->last_hdr = NULL; nl->last_size = 0; diff --git a/sysdep/unix/io.c b/sysdep/unix/io.c index 3e56a32d..a196bbe2 100644 --- a/sysdep/unix/io.c +++ b/sysdep/unix/io.c @@ -2132,7 +2132,7 @@ io_init(void) // XXX init_times(); // XXX update_times(); boot_time = current_time(); - srandom((int) now_real); + srandom((uint) (current_real_time() TO_S)); } static int short_loops = 0; diff --git a/sysdep/unix/log.c b/sysdep/unix/log.c index e564f8f2..f9dccc39 100644 --- a/sysdep/unix/log.c +++ b/sysdep/unix/log.c @@ -180,19 +180,18 @@ log_msg(const char *msg, ...) void log_rl(struct tbf *f, const char *msg, ...) { - int last_hit = f->mark; int class = 1; va_list args; /* Rate limiting is a bit tricky here as it also logs '...' during the first hit */ - if (tbf_limit(f) && last_hit) + if (tbf_limit(f) && (f->drop > 1)) return; if (*msg >= 1 && *msg <= 8) class = *msg++; va_start(args, msg); - vlog(class, (f->mark ? "..." : msg), args); + vlog(class, (f->drop ? "..." : msg), args); va_end(args); } @@ -332,7 +331,7 @@ void mrt_dump_message(struct proto *p, u16 type, u16 subtype, byte *buf, u32 len) { /* Prepare header */ - put_u32(buf+0, now_real); + put_u32(buf+0, current_real_time() TO_S); put_u16(buf+4, type); put_u16(buf+6, subtype); put_u32(buf+8, len - MRTDUMP_HDR_LENGTH); diff --git a/sysdep/unix/timer.h b/sysdep/unix/timer.h index 495d10c7..989574bf 100644 --- a/sysdep/unix/timer.h +++ b/sysdep/unix/timer.h @@ -16,7 +16,7 @@ typedef struct timer2 timer; - +#if 0 static inline timer *tm_new(pool *p) { return (void *) tm2_new(p); } @@ -44,8 +44,8 @@ static inline void tm_start_max(timer *t, bird_clock_t after) static inline timer * tm_new_set(pool *p, void (*hook)(timer *), void *data, uint rand, uint rec) { return tm2_new_init(p, hook, data, rec S_, rand S_); } +#endif -#define TIME_INFINITY ((s64) 0x7fffffffffffffff) #endif