Nest: Update statistics and rx-limit for Adj-RIB-In

This commit is contained in:
Ondrej Zajicek (work) 2018-12-11 13:52:30 +01:00
parent 682d3f7de0
commit 67d8665af5
2 changed files with 45 additions and 7 deletions

View file

@ -151,6 +151,7 @@ typedef struct rtable {
uint addr_type; /* Type of address data stored in table (NET_*) */ uint addr_type; /* Type of address data stored in table (NET_*) */
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 */
u32 rt_count; /* Number of routes in the table */
struct hostcache *hostcache; struct hostcache *hostcache;
struct rtable_config *config; /* Configuration of 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,

View file

@ -1044,6 +1044,7 @@ rte_recalculate(struct channel *c, net *net, rte *new, struct rte_src *src)
return; return;
} }
*k = old->next; *k = old->next;
table->rt_count--;
break; break;
} }
k = &old->next; k = &old->next;
@ -1063,7 +1064,7 @@ rte_recalculate(struct channel *c, net *net, rte *new, struct rte_src *src)
int old_ok = rte_is_ok(old); int old_ok = rte_is_ok(old);
struct channel_limit *l = &c->rx_limit; struct channel_limit *l = &c->rx_limit;
if (l->action && !old && new) if (l->action && !old && new && !c->in_table)
{ {
u32 all_routes = stats->imp_routes + stats->filt_routes; u32 all_routes = stats->imp_routes + stats->filt_routes;
@ -1146,6 +1147,7 @@ rte_recalculate(struct channel *c, net *net, rte *new, struct rte_src *src)
new->next = *k; new->next = *k;
*k = new; *k = new;
table->rt_count++;
} }
} }
else else
@ -1163,6 +1165,7 @@ rte_recalculate(struct channel *c, net *net, rte *new, struct rte_src *src)
new->next = net->routes; new->next = net->routes;
net->routes = new; net->routes = new;
table->rt_count++;
} }
else if (old == old_best) else if (old == old_best)
{ {
@ -1178,6 +1181,7 @@ rte_recalculate(struct channel *c, net *net, rte *new, struct rte_src *src)
{ {
new->next = net->routes; new->next = net->routes;
net->routes = new; net->routes = new;
table->rt_count++;
} }
/* Find a new optimal route (if there is any) */ /* Find a new optimal route (if there is any) */
@ -1205,6 +1209,7 @@ rte_recalculate(struct channel *c, net *net, rte *new, struct rte_src *src)
ASSERT(net->routes != NULL); ASSERT(net->routes != NULL);
new->next = net->routes->next; new->next = net->routes->next;
net->routes->next = new; net->routes->next = new;
table->rt_count++;
} }
/* The fourth (empty) case - suboptimal route was removed, nothing to do */ /* The fourth (empty) case - suboptimal route was removed, nothing to do */
} }
@ -2292,12 +2297,13 @@ rt_feed_channel_abort(struct channel *c)
int int
rte_update_in(struct channel *c, const net_addr *n, rte *new, struct rte_src *src) rte_update_in(struct channel *c, const net_addr *n, rte *new, struct rte_src *src)
{ {
struct rtable *tab = c->in_table;
rte *old, **pos; rte *old, **pos;
net *net; net *net;
if (new) if (new)
{ {
net = net_get(c->in_table, n); net = net_get(tab, n);
if (!new->pref) if (!new->pref)
new->pref = c->preference; new->pref = c->preference;
@ -2307,10 +2313,10 @@ rte_update_in(struct channel *c, const net_addr *n, rte *new, struct rte_src *sr
} }
else else
{ {
net = net_find(c->in_table, n); net = net_find(tab, n);
if (!net) if (!net)
return 0; goto drop_withdraw;
} }
/* Find the old rte */ /* Find the old rte */
@ -2318,17 +2324,36 @@ rte_update_in(struct channel *c, const net_addr *n, rte *new, struct rte_src *sr
if (old->attrs->src == src) if (old->attrs->src == src)
{ {
if (new && rte_same(old, new)) if (new && rte_same(old, new))
return 0; goto drop_update;
/* Remove the old rte */ /* Remove the old rte */
*pos = old->next; *pos = old->next;
rte_free_quick(old); rte_free_quick(old);
tab->rt_count--;
break; break;
} }
if (!new) if (!new)
return !!old; {
if (!old)
goto drop_withdraw;
return 1;
}
struct channel_limit *l = &c->rx_limit;
if (l->action && !old)
{
if (tab->rt_count >= l->limit)
channel_notify_limit(c, l, PLD_RX, tab->rt_count);
if (l->state == PLS_BLOCKED)
{
rte_trace_in(D_FILTERS, c->proto, new, "ignored [limit]");
goto drop_update;
}
}
/* Insert the new rte */ /* Insert the new rte */
rte *e = rte_do_cow(new); rte *e = rte_do_cow(new);
@ -2338,8 +2363,19 @@ rte_update_in(struct channel *c, const net_addr *n, rte *new, struct rte_src *sr
e->lastmod = current_time(); e->lastmod = current_time();
e->next = *pos; e->next = *pos;
*pos = e; *pos = e;
tab->rt_count++;
return 1; return 1;
drop_update:
c->stats.imp_updates_received++;
c->stats.imp_updates_ignored++;
rte_free(new);
return 0;
drop_withdraw:
c->stats.imp_withdraws_received++;
c->stats.imp_withdraws_ignored++;
return 0;
} }
int int
@ -2400,6 +2436,7 @@ rt_prune_sync(rtable *t, int all)
{ {
*ee = e->next; *ee = e->next;
rte_free_quick(e); rte_free_quick(e);
t->rt_count--;
} }
else else
ee = &e->next; ee = &e->next;