Garbage collector events and counters are now per table and one day
they can be made configurable if it turns out to be useful.
This commit is contained in:
parent
16c07e3d51
commit
b9626ec6ea
4 changed files with 53 additions and 39 deletions
|
@ -61,11 +61,7 @@ idval:
|
||||||
CF_ADDTO(conf, newtab)
|
CF_ADDTO(conf, newtab)
|
||||||
|
|
||||||
newtab: TABLE SYM {
|
newtab: TABLE SYM {
|
||||||
struct rtable_config *c = cfg_allocz(sizeof(struct rtable_config));
|
rt_new_table($2);
|
||||||
struct symbol *s = $2;
|
|
||||||
cf_define_symbol(s, SYM_TABLE, c);
|
|
||||||
c->name = s->name;
|
|
||||||
add_tail(&new_config->tables, &c->n);
|
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
|
@ -113,6 +113,8 @@ struct rtable_config {
|
||||||
char *name;
|
char *name;
|
||||||
struct rtable *table;
|
struct rtable *table;
|
||||||
struct proto_config *krt_attached; /* Kernel syncer attached to this table */
|
struct proto_config *krt_attached; /* Kernel syncer attached to this table */
|
||||||
|
int gc_max_ops; /* Maximum number of operations before GC is run */
|
||||||
|
int gc_min_time; /* Minimum time between two consecutive GC runs */
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct rtable {
|
typedef struct rtable {
|
||||||
|
@ -122,10 +124,14 @@ typedef struct rtable {
|
||||||
list hooks; /* List of announcement hooks */
|
list hooks; /* List of announcement hooks */
|
||||||
int pipe_busy; /* Pipe loop detection */
|
int pipe_busy; /* Pipe loop detection */
|
||||||
int use_count; /* Number of protocols using this table */
|
int use_count; /* Number of protocols using this table */
|
||||||
|
struct rtable_config *config; /* Configuration of this table */
|
||||||
struct config *deleted; /* Table doesn't exist in current configuration,
|
struct config *deleted; /* Table doesn't exist in current configuration,
|
||||||
* delete as soon as use_count becomes 0 and remove
|
* delete as soon as use_count becomes 0 and remove
|
||||||
* obstacle from this routing table.
|
* obstacle from this routing table.
|
||||||
*/
|
*/
|
||||||
|
struct event *gc_event; /* Garbage collector event */
|
||||||
|
int gc_counter; /* Number of operations since last GC */
|
||||||
|
bird_clock_t gc_time; /* Time of last GC */
|
||||||
} rtable;
|
} rtable;
|
||||||
|
|
||||||
typedef struct network {
|
typedef struct network {
|
||||||
|
@ -179,7 +185,7 @@ void rt_preconfig(struct config *);
|
||||||
void rt_commit(struct config *new, struct config *old);
|
void rt_commit(struct config *new, struct config *old);
|
||||||
void rt_lock_table(rtable *);
|
void rt_lock_table(rtable *);
|
||||||
void rt_unlock_table(rtable *);
|
void rt_unlock_table(rtable *);
|
||||||
void rt_setup(pool *, rtable *, char *);
|
void rt_setup(pool *, rtable *, char *, struct rtable_config *);
|
||||||
static inline net *net_find(rtable *tab, ip_addr addr, unsigned len) { return (net *) fib_find(&tab->fib, &addr, len); }
|
static inline net *net_find(rtable *tab, ip_addr addr, unsigned len) { return (net *) fib_find(&tab->fib, &addr, len); }
|
||||||
static inline net *net_get(rtable *tab, ip_addr addr, unsigned len) { return (net *) fib_get(&tab->fib, &addr, len); }
|
static inline net *net_get(rtable *tab, ip_addr addr, unsigned len) { return (net *) fib_get(&tab->fib, &addr, len); }
|
||||||
rte *rte_find(net *net, struct proto *p);
|
rte *rte_find(net *net, struct proto *p);
|
||||||
|
@ -195,6 +201,7 @@ void rt_dump_all(void);
|
||||||
void rt_feed_baby(struct proto *p);
|
void rt_feed_baby(struct proto *p);
|
||||||
void rt_prune(rtable *tab);
|
void rt_prune(rtable *tab);
|
||||||
void rt_prune_all(void);
|
void rt_prune_all(void);
|
||||||
|
struct rtable_config *rt_new_table(struct symbol *s);
|
||||||
|
|
||||||
struct rt_show_data {
|
struct rt_show_data {
|
||||||
ip_addr prefix;
|
ip_addr prefix;
|
||||||
|
|
|
@ -24,14 +24,8 @@
|
||||||
static slab *rte_slab;
|
static slab *rte_slab;
|
||||||
static linpool *rte_update_pool;
|
static linpool *rte_update_pool;
|
||||||
|
|
||||||
#define RT_GC_MIN_TIME 5 /* FIXME: Make configurable */
|
|
||||||
#define RT_GC_MIN_COUNT 100
|
|
||||||
|
|
||||||
static pool *rt_table_pool;
|
static pool *rt_table_pool;
|
||||||
static list routing_tables;
|
static list routing_tables;
|
||||||
static event *rt_gc_event;
|
|
||||||
static bird_clock_t rt_last_gc;
|
|
||||||
static int rt_gc_counter;
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
rte_init(struct fib_node *N)
|
rte_init(struct fib_node *N)
|
||||||
|
@ -42,15 +36,6 @@ rte_init(struct fib_node *N)
|
||||||
n->routes = NULL;
|
n->routes = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
rt_setup(pool *p, rtable *t, char *name)
|
|
||||||
{
|
|
||||||
bzero(t, sizeof(*t));
|
|
||||||
fib_init(&t->fib, p, sizeof(net), 0, rte_init);
|
|
||||||
t->name = name;
|
|
||||||
init_list(&t->hooks);
|
|
||||||
}
|
|
||||||
|
|
||||||
rte *
|
rte *
|
||||||
rte_find(net *net, struct proto *p)
|
rte_find(net *net, struct proto *p)
|
||||||
{
|
{
|
||||||
|
@ -277,8 +262,10 @@ rte_recalculate(rtable *table, net *net, struct proto *p, rte *new, ea_list *tmp
|
||||||
}
|
}
|
||||||
r->next = net->routes;
|
r->next = net->routes;
|
||||||
net->routes = r;
|
net->routes = r;
|
||||||
if (!r && rt_gc_counter++ >= RT_GC_MIN_COUNT && rt_last_gc + RT_GC_MIN_TIME <= now)
|
if (!r &&
|
||||||
ev_schedule(rt_gc_event);
|
table->gc_counter++ >= table->config->gc_max_ops &&
|
||||||
|
table->gc_time + table->config->gc_min_time <= now)
|
||||||
|
ev_schedule(table->gc_event);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (new) /* Link in the new non-optimal route */
|
if (new) /* Link in the new non-optimal route */
|
||||||
|
@ -406,17 +393,32 @@ rt_dump_all(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
rt_gc(void *unused)
|
rt_gc(void *tab)
|
||||||
{
|
{
|
||||||
rtable *t;
|
rtable *t = tab;
|
||||||
|
|
||||||
DBG("Entered routing table garbage collector after %d seconds and %d deletes\n", (int)(now - rt_last_gc), rt_gc_counter);
|
DBG("Entered routing table garbage collector for %s after %d seconds and %d deletes\n",
|
||||||
rt_prune_all();
|
t->name, (int)(now - t->gc_time), t->gc_counter);
|
||||||
rt_last_gc = now;
|
rt_prune(t);
|
||||||
rt_gc_counter = 0;
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
rt_setup(pool *p, rtable *t, char *name, struct rtable_config *cf)
|
||||||
|
{
|
||||||
|
bzero(t, sizeof(*t));
|
||||||
|
fib_init(&t->fib, p, sizeof(net), 0, rte_init);
|
||||||
|
t->name = name;
|
||||||
|
t->config = cf;
|
||||||
|
init_list(&t->hooks);
|
||||||
|
if (cf)
|
||||||
|
{
|
||||||
|
t->gc_event = ev_new(p);
|
||||||
|
t->gc_event->hook = rt_gc;
|
||||||
|
t->gc_event->data = t;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
rt_init(void)
|
rt_init(void)
|
||||||
{
|
{
|
||||||
|
@ -424,9 +426,6 @@ rt_init(void)
|
||||||
rt_table_pool = rp_new(&root_pool, "Routing tables");
|
rt_table_pool = rp_new(&root_pool, "Routing tables");
|
||||||
rte_update_pool = lp_new(rt_table_pool, 4080);
|
rte_update_pool = lp_new(rt_table_pool, 4080);
|
||||||
rte_slab = sl_new(rt_table_pool, sizeof(rte));
|
rte_slab = sl_new(rt_table_pool, sizeof(rte));
|
||||||
rt_last_gc = now;
|
|
||||||
rt_gc_event = ev_new(rt_table_pool);
|
|
||||||
rt_gc_event->hook = rt_gc;
|
|
||||||
init_list(&routing_tables);
|
init_list(&routing_tables);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -462,6 +461,8 @@ again:
|
||||||
}
|
}
|
||||||
FIB_ITERATE_END(f);
|
FIB_ITERATE_END(f);
|
||||||
DBG("Pruned %d of %d routes and %d of %d networks\n", rcnt, rdel, ncnt, ndel);
|
DBG("Pruned %d of %d routes and %d of %d networks\n", rcnt, rdel, ncnt, ndel);
|
||||||
|
tab->gc_counter = 0;
|
||||||
|
tab->gc_time = now;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -473,17 +474,26 @@ rt_prune_all(void)
|
||||||
rt_prune(t);
|
rt_prune(t);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct rtable_config *
|
||||||
|
rt_new_table(struct symbol *s)
|
||||||
|
{
|
||||||
|
struct rtable_config *c = cfg_allocz(sizeof(struct rtable_config));
|
||||||
|
|
||||||
|
cf_define_symbol(s, SYM_TABLE, c);
|
||||||
|
c->name = s->name;
|
||||||
|
add_tail(&new_config->tables, &c->n);
|
||||||
|
c->gc_max_ops = 100;
|
||||||
|
c->gc_min_time = 5;
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
rt_preconfig(struct config *c)
|
rt_preconfig(struct config *c)
|
||||||
{
|
{
|
||||||
struct symbol *s = cf_find_symbol("master");
|
struct symbol *s = cf_find_symbol("master");
|
||||||
struct rtable_config *r = cfg_allocz(sizeof(struct rtable_config));
|
|
||||||
|
|
||||||
cf_define_symbol(s, SYM_TABLE, r);
|
|
||||||
r->name = s->name;
|
|
||||||
init_list(&c->tables);
|
init_list(&c->tables);
|
||||||
add_tail(&c->tables, &r->n);
|
c->master_rtc = rt_new_table(s);
|
||||||
c->master_rtc = r;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -526,6 +536,7 @@ rt_commit(struct config *new, struct config *old)
|
||||||
r = sym->def;
|
r = sym->def;
|
||||||
r->table = ot;
|
r->table = ot;
|
||||||
ot->name = r->name;
|
ot->name = r->name;
|
||||||
|
ot->config = r;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -544,7 +555,7 @@ rt_commit(struct config *new, struct config *old)
|
||||||
{
|
{
|
||||||
rtable *t = mb_alloc(rt_table_pool, sizeof(struct rtable));
|
rtable *t = mb_alloc(rt_table_pool, sizeof(struct rtable));
|
||||||
DBG("\t%s: created\n", r->name);
|
DBG("\t%s: created\n", r->name);
|
||||||
rt_setup(rt_table_pool, t, r->name);
|
rt_setup(rt_table_pool, t, r->name, r);
|
||||||
add_tail(&routing_tables, &t->n);
|
add_tail(&routing_tables, &t->n);
|
||||||
r->table = t;
|
r->table = t;
|
||||||
}
|
}
|
||||||
|
|
|
@ -385,7 +385,7 @@ static void
|
||||||
krt_learn_init(struct krt_proto *p)
|
krt_learn_init(struct krt_proto *p)
|
||||||
{
|
{
|
||||||
if (KRT_CF->learn)
|
if (KRT_CF->learn)
|
||||||
rt_setup(p->p.pool, &p->krt_table, "Inherited");
|
rt_setup(p->p.pool, &p->krt_table, "Inherited", NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
Loading…
Reference in a new issue