Timers: Fix TBF and some last remains
This commit is contained in:
parent
3b3b0910ff
commit
574b232427
11 changed files with 45 additions and 50 deletions
|
@ -384,7 +384,7 @@ config_confirm(void)
|
||||||
if (config_timer->expires == 0)
|
if (config_timer->expires == 0)
|
||||||
return CONF_NOTHING;
|
return CONF_NOTHING;
|
||||||
|
|
||||||
tm_stop(config_timer);
|
tm2_stop(config_timer);
|
||||||
|
|
||||||
return CONF_CONFIRM;
|
return CONF_CONFIRM;
|
||||||
}
|
}
|
||||||
|
@ -420,7 +420,7 @@ config_undo(void)
|
||||||
return CONF_NOTHING;
|
return CONF_NOTHING;
|
||||||
|
|
||||||
undo_available = 0;
|
undo_available = 0;
|
||||||
tm_stop(config_timer);
|
tm2_stop(config_timer);
|
||||||
|
|
||||||
if (configuring)
|
if (configuring)
|
||||||
{
|
{
|
||||||
|
@ -468,7 +468,7 @@ config_init(void)
|
||||||
config_event = ev_new(&root_pool);
|
config_event = ev_new(&root_pool);
|
||||||
config_event->hook = config_done;
|
config_event->hook = config_done;
|
||||||
|
|
||||||
config_timer = tm_new(&root_pool);
|
config_timer = tm2_new(&root_pool);
|
||||||
config_timer->hook = config_timeout;
|
config_timer->hook = config_timeout;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -69,7 +69,7 @@ static inline int u64_cmp(u64 i1, u64 i2)
|
||||||
/* Microsecond time */
|
/* Microsecond time */
|
||||||
|
|
||||||
typedef s64 btime;
|
typedef s64 btime;
|
||||||
typedef s64 bird_clock_t;
|
//typedef s64 bird_clock_t;
|
||||||
|
|
||||||
#define S_ * (btime) 1000000
|
#define S_ * (btime) 1000000
|
||||||
#define MS_ * (btime) 1000
|
#define MS_ * (btime) 1000
|
||||||
|
@ -85,37 +85,23 @@ typedef s64 bird_clock_t;
|
||||||
#define NS /1000
|
#define NS /1000
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define TIME_INFINITY ((s64) 0x7fffffffffffffff)
|
||||||
|
|
||||||
|
|
||||||
/* Rate limiting */
|
/* Rate limiting */
|
||||||
|
|
||||||
struct tbf {
|
struct tbf {
|
||||||
bird_clock_t timestamp; /* Last update */
|
btime timestamp; /* Last update */
|
||||||
u16 count; /* Available tokens */
|
u64 count; /* Available micro-tokens */
|
||||||
u16 burst; /* Max number of tokens */
|
u16 burst; /* Max number of tokens */
|
||||||
u16 rate; /* Rate of replenishment */
|
u16 rate; /* Rate of replenishment (tokens / sec) */
|
||||||
u16 mark; /* Whether last op was limited */
|
u32 drop; /* Number of failed request since last successful */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Default TBF values for rate limiting log messages */
|
/* Default TBF values for rate limiting log messages */
|
||||||
#define TBF_DEFAULT_LOG_LIMITS { .rate = 1, .burst = 5 }
|
#define TBF_DEFAULT_LOG_LIMITS { .rate = 1, .burst = 5 }
|
||||||
|
|
||||||
void tbf_update(struct tbf *f);
|
int tbf_limit(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;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Logging and dying */
|
/* Logging and dying */
|
||||||
|
|
31
lib/tbf.c
31
lib/tbf.c
|
@ -10,21 +10,28 @@
|
||||||
#include "nest/bird.h"
|
#include "nest/bird.h"
|
||||||
#include "lib/timer.h"
|
#include "lib/timer.h"
|
||||||
|
|
||||||
void
|
int
|
||||||
tbf_update(struct tbf *f)
|
tbf_limit(struct tbf *f)
|
||||||
{
|
{
|
||||||
bird_clock_t delta = now - f->timestamp;
|
btime delta = current_time() - f->timestamp;
|
||||||
|
|
||||||
if (delta == 0)
|
if (delta > 0)
|
||||||
return;
|
|
||||||
|
|
||||||
f->timestamp = now;
|
|
||||||
|
|
||||||
if ((0 < delta) && (delta < f->burst))
|
|
||||||
{
|
{
|
||||||
u32 next = f->count + delta * f->rate;
|
u64 next = f->count + delta * f->rate;
|
||||||
f->count = MIN(next, f->burst);
|
u64 burst = (u64) f->burst << 20;
|
||||||
|
f->count = MIN(next, burst);
|
||||||
|
f->timestamp += delta;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (f->count < 1000000)
|
||||||
|
{
|
||||||
|
f->drop++;
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
f->count = f->burst;
|
{
|
||||||
|
f->count -= 1000000;
|
||||||
|
f->drop = 0;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,8 +46,8 @@ extern struct timeloop main_timeloop;
|
||||||
btime current_time(void);
|
btime current_time(void);
|
||||||
btime current_real_time(void);
|
btime current_real_time(void);
|
||||||
|
|
||||||
#define now (current_time() TO_S)
|
//#define now (current_time() TO_S)
|
||||||
#define now_real (current_real_time() TO_S)
|
//#define now_real (current_real_time() TO_S)
|
||||||
extern btime boot_time;
|
extern btime boot_time;
|
||||||
|
|
||||||
timer2 *tm2_new(pool *p);
|
timer2 *tm2_new(pool *p);
|
||||||
|
|
|
@ -1288,7 +1288,7 @@ protos_build(void)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
proto_pool = rp_new(&root_pool, "Protocols");
|
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;
|
proto_shutdown_timer->hook = proto_shutdown_loop;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -58,7 +58,7 @@
|
||||||
log_rl(&p->log_lsa_tbf, L_REMOTE "%s: " msg, p->p.name, args)
|
log_rl(&p->log_lsa_tbf, L_REMOTE "%s: " msg, p->p.name, args)
|
||||||
|
|
||||||
#define LOG_LSA2(msg, 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)
|
log(L_REMOTE "%s: " msg, p->p.name, args); } while(0)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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.
|
* have the same CSN. We are using real time, but enforcing monotonicity.
|
||||||
*/
|
*/
|
||||||
if (ifa->cf->auth_type == RIP_AUTH_CRYPTO)
|
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
|
static void
|
||||||
|
|
|
@ -151,7 +151,7 @@ nl_open_sock(struct nl_sock *nl)
|
||||||
nl->fd = socket(PF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
|
nl->fd = socket(PF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
|
||||||
if (nl->fd < 0)
|
if (nl->fd < 0)
|
||||||
die("Unable to open rtnetlink socket: %m");
|
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->rx_buffer = xmalloc(NL_RX_SIZE);
|
||||||
nl->last_hdr = NULL;
|
nl->last_hdr = NULL;
|
||||||
nl->last_size = 0;
|
nl->last_size = 0;
|
||||||
|
|
|
@ -2132,7 +2132,7 @@ io_init(void)
|
||||||
// XXX init_times();
|
// XXX init_times();
|
||||||
// XXX update_times();
|
// XXX update_times();
|
||||||
boot_time = current_time();
|
boot_time = current_time();
|
||||||
srandom((int) now_real);
|
srandom((uint) (current_real_time() TO_S));
|
||||||
}
|
}
|
||||||
|
|
||||||
static int short_loops = 0;
|
static int short_loops = 0;
|
||||||
|
|
|
@ -180,19 +180,18 @@ log_msg(const char *msg, ...)
|
||||||
void
|
void
|
||||||
log_rl(struct tbf *f, const char *msg, ...)
|
log_rl(struct tbf *f, const char *msg, ...)
|
||||||
{
|
{
|
||||||
int last_hit = f->mark;
|
|
||||||
int class = 1;
|
int class = 1;
|
||||||
va_list args;
|
va_list args;
|
||||||
|
|
||||||
/* Rate limiting is a bit tricky here as it also logs '...' during the first hit */
|
/* 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;
|
return;
|
||||||
|
|
||||||
if (*msg >= 1 && *msg <= 8)
|
if (*msg >= 1 && *msg <= 8)
|
||||||
class = *msg++;
|
class = *msg++;
|
||||||
|
|
||||||
va_start(args, msg);
|
va_start(args, msg);
|
||||||
vlog(class, (f->mark ? "..." : msg), args);
|
vlog(class, (f->drop ? "..." : msg), args);
|
||||||
va_end(args);
|
va_end(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -332,7 +331,7 @@ void
|
||||||
mrt_dump_message(struct proto *p, u16 type, u16 subtype, byte *buf, u32 len)
|
mrt_dump_message(struct proto *p, u16 type, u16 subtype, byte *buf, u32 len)
|
||||||
{
|
{
|
||||||
/* Prepare header */
|
/* 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+4, type);
|
||||||
put_u16(buf+6, subtype);
|
put_u16(buf+6, subtype);
|
||||||
put_u32(buf+8, len - MRTDUMP_HDR_LENGTH);
|
put_u32(buf+8, len - MRTDUMP_HDR_LENGTH);
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
|
|
||||||
|
|
||||||
typedef struct timer2 timer;
|
typedef struct timer2 timer;
|
||||||
|
#if 0
|
||||||
static inline timer *tm_new(pool *p)
|
static inline timer *tm_new(pool *p)
|
||||||
{ return (void *) tm2_new(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)
|
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_); }
|
{ return tm2_new_init(p, hook, data, rec S_, rand S_); }
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
#define TIME_INFINITY ((s64) 0x7fffffffffffffff)
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in a new issue