1
0
mirror of https://gitlab.labs.nic.cz/labs/bird.git synced 2024-05-11 16:54:54 +00:00
This commit is contained in:
Maria Matejka
2024-05-06 23:58:04 +02:00
parent 8cc35a71ea
commit 78d95885ee
3 changed files with 54 additions and 70 deletions

View File

@@ -608,7 +608,7 @@ rtable *rt_setup(pool *, struct rtable_config *);
struct rt_export_feed *rt_net_feed(rtable *t, const net_addr *a);
rte rt_net_best(rtable *t, const net_addr *a);
int rt_examine(rtable *t, net_addr *a, struct channel *c, const struct filter *filter);
rte *rt_export_merged(struct channel *c, const net_addr *n, rte *feed, uint count, linpool *pool, int silent);
rte *rt_export_merged(struct channel *c, const struct rt_export_feed *feed, linpool *pool, int silent);
void rt_refresh_begin(struct rt_import_request *);
void rt_refresh_end(struct rt_import_request *);
void rt_schedule_prune(struct rtable_private *t);

View File

@@ -96,7 +96,7 @@ rt_show_rte(struct cli *c, byte *ia, rte *e, struct rt_show_data *d, int primary
}
static void
rt_show_net(struct rt_show_data *d, const net_addr *n, rte *feed, uint count)
rt_show_net(struct rt_show_data *d, const struct rt_export_feed *feed)
{
struct cli *c = d->cli;
byte ia[NET_MAX_TEXT_LENGTH+16+1];
@@ -111,10 +111,13 @@ rt_show_net(struct rt_show_data *d, const net_addr *n, rte *feed, uint count)
uint last_label = 0;
int pass = 0;
for (uint i = 0; i < count; i++)
for (uint i = 0; i < feed->count_routes; i++)
{
#define e (feed[i])
if (!d->tab->prefilter && (rte_is_filtered(&feed[i]) != d->filtered))
rte *e = &feed->block[i];
if (e->flags & REF_OBSOLETE)
break;
if (!d->tab->prefilter && (rte_is_filtered(e) != d->filtered))
continue;
d->rt_counter++;
@@ -125,10 +128,10 @@ rt_show_net(struct rt_show_data *d, const net_addr *n, rte *feed, uint count)
continue;
if (d->tab->prefilter)
if (e.sender != d->tab->prefilter->in_req.hook)
if (e->sender != d->tab->prefilter->in_req.hook)
continue;
else while (e.attrs->next)
e.attrs = e.attrs->next;
else
e->attrs = ea_strip_to(e->attrs, BIT32_ALL(EALS_PREIMPORT));
/* Export channel is down, do not try to export routes to it */
if (ec && (rt_export_get_state(&ec->out_req) == TES_DOWN))
@@ -136,7 +139,7 @@ rt_show_net(struct rt_show_data *d, const net_addr *n, rte *feed, uint count)
if (d->export_mode == RSEM_EXPORTED)
{
if (!bmap_test(&ec->export_accepted_map, e.id))
if (!bmap_test(&ec->export_accepted_map, e->id))
goto skip;
// if (ec->ra_mode != RA_ANY)
@@ -146,17 +149,17 @@ rt_show_net(struct rt_show_data *d, const net_addr *n, rte *feed, uint count)
{
/* Special case for merged export */
pass = 1;
rte *em = rt_export_merged(ec, n, feed, count, tmp_linpool, 1);
rte *em = rt_export_merged(ec, feed, tmp_linpool, 1);
if (em)
e = *em;
e = em;
else
goto skip;
}
else if (d->export_mode)
{
struct proto *ep = ec->proto;
int ic = ep->preexport ? ep->preexport(ec, &e) : 0;
int ic = ep->preexport ? ep->preexport(ec, e) : 0;
if (ec->ra_mode == RA_OPTIMAL || ec->ra_mode == RA_MERGED)
pass = 1;
@@ -172,7 +175,7 @@ rt_show_net(struct rt_show_data *d, const net_addr *n, rte *feed, uint count)
* command may change the export filter and do not update routes.
*/
int do_export = (ic > 0) ||
(f_run(ec->out_filter, &e, FF_SILENT) <= F_ACCEPT);
(f_run(ec->out_filter, e, FF_SILENT) <= F_ACCEPT);
if (do_export != (d->export_mode == RSEM_EXPORT))
goto skip;
@@ -182,27 +185,27 @@ rt_show_net(struct rt_show_data *d, const net_addr *n, rte *feed, uint count)
}
}
if (d->show_protocol && (&d->show_protocol->sources != e.src->owner))
if (d->show_protocol && (&d->show_protocol->sources != e->src->owner))
goto skip;
if (f_run(d->filter, &e, 0) > F_ACCEPT)
if (f_run(d->filter, e, 0) > F_ACCEPT)
goto skip;
if (d->stats < 2)
{
uint label = ea_get_int(e.attrs, &ea_gen_mpls_label, ~0U);
uint label = ea_get_int(e->attrs, &ea_gen_mpls_label, ~0U);
if (first_show || (last_label != label))
{
if (!~label)
net_format(n, ia, sizeof(ia));
net_format(feed->ni->addr, ia, sizeof(ia));
else
bsnprintf(ia, sizeof(ia), "%N mpls %d", n, label);
bsnprintf(ia, sizeof(ia), "%N mpls %d", feed->ni->addr, label);
}
else
ia[0] = 0;
rt_show_rte(c, ia, &e, d, !d->tab->prefilter && !i);
rt_show_rte(c, ia, e, d, !d->tab->prefilter && !i);
first_show = 0;
last_label = label;
}
@@ -289,7 +292,7 @@ rt_show_cont(struct cli *c)
return rt_show_done(d);
case RT_EXPORT_FEED:
if (u->feed->count_routes)
rt_show_net(d, u->feed->block[0].net, u->feed->block, u->feed->count_routes);
rt_show_net(d, u->feed);
break;
}
}

View File

@@ -862,77 +862,58 @@ rt_net_is_feeding(struct rt_export_request *req, const net_addr *n)
}
static void
rt_notify_accepted(struct channel *c, struct rt_export_feed *feed)
rt_notify_accepted(struct channel *c, const struct rt_export_feed *feed)
{
const rte *old_best, *new_best;
rte *old_best, *new_best;
_Bool feeding = rt_net_is_feeding(&c->out_req, feed->ni->addr);
_Bool idempotent = 0;
for (uint i = 0; i < feed->count_routes; i++)
{
rte *r = &feed->block[i];
/* Has been already rejected, won't bother with it */
if (feeding)
bmap_clear(&c->export_reject_map, r->id);
else if (bmap_test(&c->export_reject_map, r->id))
continue;
/* Previously exported */
if (!old_best && bmap_test(&c->export_map, r->id))
if (!old_best && bmap_test(&c->export_accepted_map, r->id))
{
if (new_best)
old_best = r;
/* Is still the best and need not be refed anyway */
if (!new_best && !feeding)
{
/* is superseded */
old_best = r;
break;
}
else if (feeding)
/* is superseded but maybe by a new version of itself */
old_best = r;
else
{
/* is still best */
DBG("rt_notify_accepted: idempotent\n");
return;
idempotent = 1;
new_best = r;
}
}
if (!rte_is_valid(r))
bmap_set(&c->export_reject_map, r->id);
/* Unflag obsolete routes */
if (r->flags & REF_OBSOLETE)
bmap_clear(&c->export_rejected_map, r->id);
/* Mark invalid as rejected */
else if (!rte_is_valid(r))
bmap_set(&c->export_rejected_map, r->id);
/* Already rejected */
else if (!feeding && bmap_test(&c->export_rejected_map, r->id))
;
/* No new best route yet and this is a valid candidate */
else if (!new_best)
{
/* This branch should not be executed if this route is old best */
ASSERT_DIE(r != old_best);
/* Have no new best route yet, try this route not seen before */
new_best = export_filter(c, r, 0);
DBG("rt_notify_accepted: checking route id %u: %s\n", feed[i]->id, new_best ? "ok" : "no");
if (old_best)
break;
DBG("rt_notify_accepted: checking route id %u: %s\n", r->id, new_best ? "ok" : "no");
}
}
/* Check obsolete routes for previously exported */
RPE_WALK(first, rpe, NULL)
{
channel_rpe_mark_seen(c, rpe);
if (rpe->old)
{
if (bmap_test(&c->export_map, rpe->old->id))
{
ASSERT_DIE(old_best == NULL);
old_best = rpe->old;
}
}
if (rpe == last)
break;
}
/* Nothing to export */
if (new_best || old_best)
do_rt_notify(c, n, new_best, old_best);
if (!idempotent && (new_best || old_best))
do_rt_notify(c, feed->ni->addr, new_best, old_best);
else
DBG("rt_notify_accepted: nothing to export\n");
if (refeeding)
channel_net_mark_refed(c, n);
}
void
@@ -965,7 +946,7 @@ channel_notify_accepted(void *_channel)
}
rte *
rt_export_merged(struct channel *c, const net_addr *n, const rte **feed, uint count, linpool *pool, int silent)
rt_export_merged(struct channel *c, const struct rt_export_feed *feed, linpool *pool, int silent)
{
_Thread_local static rte rloc;