mirror of
https://gitlab.nic.cz/labs/bird.git
synced 2024-11-08 12:18:42 +00:00
Fixed secondary route export
This commit is contained in:
parent
d53582c9a1
commit
5ea6423cb9
@ -108,8 +108,6 @@ void
|
|||||||
channel_request_full_refeed(struct channel *c)
|
channel_request_full_refeed(struct channel *c)
|
||||||
{
|
{
|
||||||
rt_export_refeed(&c->out_req, NULL);
|
rt_export_refeed(&c->out_req, NULL);
|
||||||
bmap_reset(&c->export_accepted_map, 16);
|
|
||||||
bmap_reset(&c->export_rejected_map, 16);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
18
nest/route.h
18
nest/route.h
@ -331,9 +331,21 @@ static inline bool
|
|||||||
rt_net_is_feeding_request(struct rt_export_request *req, const net_addr *n)
|
rt_net_is_feeding_request(struct rt_export_request *req, const net_addr *n)
|
||||||
{
|
{
|
||||||
struct netindex *ni = NET_TO_INDEX(n);
|
struct netindex *ni = NET_TO_INDEX(n);
|
||||||
return
|
switch (rt_export_get_state(req))
|
||||||
!bmap_test(&req->feed_map, ni->index)
|
{
|
||||||
&& rt_net_is_feeding_feeder(&req->feeder, n);
|
case TES_PARTIAL:
|
||||||
|
case TES_FEEDING:
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Already fed */
|
||||||
|
if (bmap_test(&req->feed_map, ni->index))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return rt_net_is_feeding_feeder(&req->feeder, n);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define rt_net_is_feeding(h, n) _Generic((h), \
|
#define rt_net_is_feeding(h, n) _Generic((h), \
|
||||||
|
@ -103,9 +103,7 @@ rt_export_get(struct rt_export_request *r)
|
|||||||
else if (feed = rt_export_next_feed(&r->feeder))
|
else if (feed = rt_export_next_feed(&r->feeder))
|
||||||
{
|
{
|
||||||
/* Feeding more */
|
/* Feeding more */
|
||||||
bmap_set(&r->feed_map, feed->ni->index);
|
|
||||||
rtex_trace(r, D_ROUTES, "Feeding %N", feed->ni->addr);
|
rtex_trace(r, D_ROUTES, "Feeding %N", feed->ni->addr);
|
||||||
|
|
||||||
EXPORT_FOUND(RT_EXPORT_FEED);
|
EXPORT_FOUND(RT_EXPORT_FEED);
|
||||||
}
|
}
|
||||||
else if (rt_export_get_state(r) == TES_DOWN)
|
else if (rt_export_get_state(r) == TES_DOWN)
|
||||||
@ -158,7 +156,6 @@ rt_export_get(struct rt_export_request *r)
|
|||||||
feed = e->feed_net(e, u, ni->index, NULL, NULL, update);
|
feed = e->feed_net(e, u, ni->index, NULL, NULL, update);
|
||||||
}
|
}
|
||||||
|
|
||||||
bmap_set(&r->feed_map, ni->index);
|
|
||||||
ASSERT_DIE(feed && (feed != &rt_feed_index_out_of_range));
|
ASSERT_DIE(feed && (feed != &rt_feed_index_out_of_range));
|
||||||
|
|
||||||
EXPORT_FOUND(RT_EXPORT_FEED);
|
EXPORT_FOUND(RT_EXPORT_FEED);
|
||||||
@ -193,6 +190,8 @@ rt_export_release(const struct rt_export_union *u)
|
|||||||
for (uint i = 0; i < u->feed->count_exports; i++)
|
for (uint i = 0; i < u->feed->count_exports; i++)
|
||||||
bmap_set(&r->seq_map, u->feed->exports[i]);
|
bmap_set(&r->seq_map, u->feed->exports[i]);
|
||||||
|
|
||||||
|
bmap_set(&r->feed_map, u->feed->ni->index);
|
||||||
|
|
||||||
if (!u->update)
|
if (!u->update)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -1081,13 +1081,21 @@ rt_notify_basic(struct channel *c, const rte *new, const rte *old)
|
|||||||
do_rt_notify(c, np ? np->net : old->net, np, old);
|
do_rt_notify(c, np ? np->net : old->net, np, old);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
#define RT_NOTIFY_DEBUG(fmt...) log(L_TRACE "rt_notify_accepted: " fmt, ##fmt)
|
||||||
|
#else
|
||||||
|
#define RT_NOTIFY_DEBUG(...)
|
||||||
|
#endif
|
||||||
|
|
||||||
static void
|
static void
|
||||||
rt_notify_accepted(struct channel *c, const struct rt_export_feed *feed)
|
rt_notify_accepted(struct channel *c, const struct rt_export_feed *feed)
|
||||||
{
|
{
|
||||||
rte *old_best, *new_best;
|
rte *old_best = NULL, *new_best = NULL;
|
||||||
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;
|
bool idempotent = 0;
|
||||||
|
|
||||||
|
RT_NOTIFY_DEBUG("%s feed for %N with %u routes", feeding ? "refeed" : "regular", feed->ni->addr, feed->count_routes);
|
||||||
|
|
||||||
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];
|
||||||
@ -1095,45 +1103,62 @@ rt_notify_accepted(struct channel *c, const struct rt_export_feed *feed)
|
|||||||
/* Previously exported */
|
/* Previously exported */
|
||||||
if (!old_best && bmap_test(&c->export_accepted_map, r->id))
|
if (!old_best && bmap_test(&c->export_accepted_map, r->id))
|
||||||
{
|
{
|
||||||
|
RT_NOTIFY_DEBUG("route %u id %u previously exported, is old best", i, r->id);
|
||||||
old_best = r;
|
old_best = r;
|
||||||
|
|
||||||
|
/* Is being withdrawn */
|
||||||
|
if (r->flags & REF_OBSOLETE)
|
||||||
|
RT_NOTIFY_DEBUG("route %u id %u is also obsolete", i, r->id);
|
||||||
|
|
||||||
/* Is still the best and need not be refed anyway */
|
/* Is still the best and need not be refed anyway */
|
||||||
if (!new_best && !feeding)
|
else if (!new_best && !feeding)
|
||||||
{
|
{
|
||||||
idempotent = 1;
|
RT_NOTIFY_DEBUG("route %u id %u is also new best (idempotent)", i, r->id);
|
||||||
new_best = r;
|
new_best = r;
|
||||||
|
idempotent = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Unflag obsolete routes */
|
/* Unflag obsolete routes */
|
||||||
if (r->flags & REF_OBSOLETE)
|
else if (r->flags & REF_OBSOLETE)
|
||||||
|
{
|
||||||
|
RT_NOTIFY_DEBUG("route %u id %u is obsolete", i, r->id);
|
||||||
bmap_clear(&c->export_rejected_map, r->id);
|
bmap_clear(&c->export_rejected_map, r->id);
|
||||||
|
}
|
||||||
|
|
||||||
/* Mark invalid as rejected */
|
/* Mark invalid as rejected */
|
||||||
else if (!rte_is_valid(r))
|
else if (!rte_is_valid(r))
|
||||||
|
{
|
||||||
|
RT_NOTIFY_DEBUG("route %u id %u is invalid", i, r->id);
|
||||||
bmap_set(&c->export_rejected_map, r->id);
|
bmap_set(&c->export_rejected_map, r->id);
|
||||||
|
}
|
||||||
|
|
||||||
/* Already rejected */
|
/* Already rejected */
|
||||||
else if (!feeding && bmap_test(&c->export_rejected_map, r->id))
|
else if (!feeding && bmap_test(&c->export_rejected_map, r->id))
|
||||||
;
|
RT_NOTIFY_DEBUG("route %u id %u has been rejected before", i, r->id);
|
||||||
|
|
||||||
/* No new best route yet and this is a valid candidate */
|
/* 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 */
|
/* This branch should not be executed if this route is old best */
|
||||||
ASSERT_DIE(r != old_best);
|
ASSERT_DIE(feeding || (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", r->id, new_best ? "ok" : "no");
|
RT_NOTIFY_DEBUG("route %u id %u is a new_best candidate %s", i, r->id,
|
||||||
|
new_best ? "and is accepted" : "but got rejected");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Just a debug message for the last case */
|
||||||
|
else
|
||||||
|
RT_NOTIFY_DEBUG("route %u id %u is suboptimal, not checking", i, r->id);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Nothing to export */
|
/* Nothing to export */
|
||||||
if (!idempotent && (new_best || old_best))
|
if (!idempotent && (new_best || old_best))
|
||||||
do_rt_notify(c, feed->ni->addr, 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");
|
RT_NOTIFY_DEBUG("nothing to export for %N", feed->ni->addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
Loading…
Reference in New Issue
Block a user