mirror of
https://gitlab.labs.nic.cz/labs/bird.git
synced 2024-05-11 16:54:54 +00:00
TMP
This commit is contained in:
@@ -608,7 +608,7 @@ rtable *rt_setup(pool *, struct rtable_config *);
|
|||||||
struct rt_export_feed *rt_net_feed(rtable *t, const net_addr *a);
|
struct rt_export_feed *rt_net_feed(rtable *t, const net_addr *a);
|
||||||
rte rt_net_best(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);
|
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_begin(struct rt_import_request *);
|
||||||
void rt_refresh_end(struct rt_import_request *);
|
void rt_refresh_end(struct rt_import_request *);
|
||||||
void rt_schedule_prune(struct rtable_private *t);
|
void rt_schedule_prune(struct rtable_private *t);
|
||||||
|
@@ -96,7 +96,7 @@ rt_show_rte(struct cli *c, byte *ia, rte *e, struct rt_show_data *d, int primary
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
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;
|
struct cli *c = d->cli;
|
||||||
byte ia[NET_MAX_TEXT_LENGTH+16+1];
|
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;
|
uint last_label = 0;
|
||||||
int pass = 0;
|
int pass = 0;
|
||||||
|
|
||||||
for (uint i = 0; i < count; i++)
|
for (uint i = 0; i < feed->count_routes; i++)
|
||||||
{
|
{
|
||||||
#define e (feed[i])
|
rte *e = &feed->block[i];
|
||||||
if (!d->tab->prefilter && (rte_is_filtered(&feed[i]) != d->filtered))
|
if (e->flags & REF_OBSOLETE)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (!d->tab->prefilter && (rte_is_filtered(e) != d->filtered))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
d->rt_counter++;
|
d->rt_counter++;
|
||||||
@@ -125,10 +128,10 @@ rt_show_net(struct rt_show_data *d, const net_addr *n, rte *feed, uint count)
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (d->tab->prefilter)
|
if (d->tab->prefilter)
|
||||||
if (e.sender != d->tab->prefilter->in_req.hook)
|
if (e->sender != d->tab->prefilter->in_req.hook)
|
||||||
continue;
|
continue;
|
||||||
else while (e.attrs->next)
|
else
|
||||||
e.attrs = e.attrs->next;
|
e->attrs = ea_strip_to(e->attrs, BIT32_ALL(EALS_PREIMPORT));
|
||||||
|
|
||||||
/* Export channel is down, do not try to export routes to it */
|
/* Export channel is down, do not try to export routes to it */
|
||||||
if (ec && (rt_export_get_state(&ec->out_req) == TES_DOWN))
|
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 (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;
|
goto skip;
|
||||||
|
|
||||||
// if (ec->ra_mode != RA_ANY)
|
// 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 */
|
/* Special case for merged export */
|
||||||
pass = 1;
|
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)
|
if (em)
|
||||||
e = *em;
|
e = em;
|
||||||
else
|
else
|
||||||
goto skip;
|
goto skip;
|
||||||
}
|
}
|
||||||
else if (d->export_mode)
|
else if (d->export_mode)
|
||||||
{
|
{
|
||||||
struct proto *ep = ec->proto;
|
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)
|
if (ec->ra_mode == RA_OPTIMAL || ec->ra_mode == RA_MERGED)
|
||||||
pass = 1;
|
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.
|
* command may change the export filter and do not update routes.
|
||||||
*/
|
*/
|
||||||
int do_export = (ic > 0) ||
|
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))
|
if (do_export != (d->export_mode == RSEM_EXPORT))
|
||||||
goto skip;
|
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;
|
goto skip;
|
||||||
|
|
||||||
if (f_run(d->filter, &e, 0) > F_ACCEPT)
|
if (f_run(d->filter, e, 0) > F_ACCEPT)
|
||||||
goto skip;
|
goto skip;
|
||||||
|
|
||||||
if (d->stats < 2)
|
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 (first_show || (last_label != label))
|
||||||
{
|
{
|
||||||
if (!~label)
|
if (!~label)
|
||||||
net_format(n, ia, sizeof(ia));
|
net_format(feed->ni->addr, ia, sizeof(ia));
|
||||||
else
|
else
|
||||||
bsnprintf(ia, sizeof(ia), "%N mpls %d", n, label);
|
bsnprintf(ia, sizeof(ia), "%N mpls %d", feed->ni->addr, label);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
ia[0] = 0;
|
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;
|
first_show = 0;
|
||||||
last_label = label;
|
last_label = label;
|
||||||
}
|
}
|
||||||
@@ -289,7 +292,7 @@ rt_show_cont(struct cli *c)
|
|||||||
return rt_show_done(d);
|
return rt_show_done(d);
|
||||||
case RT_EXPORT_FEED:
|
case RT_EXPORT_FEED:
|
||||||
if (u->feed->count_routes)
|
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;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -862,77 +862,58 @@ rt_net_is_feeding(struct rt_export_request *req, const net_addr *n)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
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 feeding = rt_net_is_feeding(&c->out_req, feed->ni->addr);
|
||||||
|
_Bool idempotent = 0;
|
||||||
|
|
||||||
for (uint i = 0; i < feed->count_routes; i++)
|
for (uint i = 0; i < feed->count_routes; i++)
|
||||||
{
|
{
|
||||||
rte *r = &feed->block[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 */
|
/* 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 */
|
idempotent = 1;
|
||||||
old_best = r;
|
new_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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
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)
|
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 */
|
/* Have no new best route yet, try this route not seen before */
|
||||||
new_best = export_filter(c, r, 0);
|
new_best = export_filter(c, r, 0);
|
||||||
DBG("rt_notify_accepted: checking route id %u: %s\n", feed[i]->id, new_best ? "ok" : "no");
|
DBG("rt_notify_accepted: checking route id %u: %s\n", r->id, new_best ? "ok" : "no");
|
||||||
if (old_best)
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* 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 */
|
/* Nothing to export */
|
||||||
if (new_best || old_best)
|
if (!idempotent && (new_best || old_best))
|
||||||
do_rt_notify(c, n, new_best, old_best);
|
do_rt_notify(c, feed->ni->addr, new_best, old_best);
|
||||||
else
|
else
|
||||||
DBG("rt_notify_accepted: nothing to export\n");
|
DBG("rt_notify_accepted: nothing to export\n");
|
||||||
|
|
||||||
if (refeeding)
|
|
||||||
channel_net_mark_refed(c, n);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -965,7 +946,7 @@ channel_notify_accepted(void *_channel)
|
|||||||
}
|
}
|
||||||
|
|
||||||
rte *
|
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;
|
_Thread_local static rte rloc;
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user