0
0
mirror of https://gitlab.nic.cz/labs/bird.git synced 2024-12-22 09:41:54 +00:00

Kernel: protocol shuts down synchronously

Before this commit, on kernel shutdown, the routes were re-exported by
the regular export but treated as withdraw. This was too hairy and
caused unnecessary complexity of the protocol's state machine.

Instead of that, we found out that it makes more sense to just refeed
the routes synchronously and convert to withdraw. This is done by the
direct export access instead of the channel.

It would (maybe) make more sense to run export filters on this in case
the export filter updates the krt_metric attribute, but as this doesn't
work on regular withdraw anyway, it's better for now to just let it be
and maybe somebody in the future fixes this issue.
This commit is contained in:
Katerina Kubecova 2024-09-27 14:54:21 +02:00 committed by Maria Matejka
parent e787a9210f
commit 716472957b
2 changed files with 24 additions and 23 deletions

View File

@ -390,9 +390,6 @@ krt_got_route(struct krt_proto *p, rte *e, s8 src)
#endif #endif
/* The rest is for KRT_SRC_BIRD (or KRT_SRC_UNKNOWN) */ /* The rest is for KRT_SRC_BIRD (or KRT_SRC_UNKNOWN) */
/* Deleting all routes if final flush is requested */
if (p->sync_state == KPS_FLUSHING)
goto delete;
/* We wait for the initial feed to have correct installed state */ /* We wait for the initial feed to have correct installed state */
if (!p->ready) if (!p->ready)
@ -463,8 +460,6 @@ krt_init_scan(struct krt_proto *p)
log(L_WARN "%s: Can't scan, still pruning", p->p.name); log(L_WARN "%s: Can't scan, still pruning", p->p.name);
return 0; return 0;
case KPS_FLUSHING:
bug("Can't scan, flushing");
} }
bug("Bad kernel sync state"); bug("Bad kernel sync state");
@ -488,8 +483,6 @@ krt_prune(struct krt_proto *p)
case KPS_PRUNING: case KPS_PRUNING:
bug("Kernel scan double-prune"); bug("Kernel scan double-prune");
case KPS_FLUSHING:
bug("Attemted kernel scan prune when flushing");
} }
} }
@ -704,9 +697,6 @@ krt_rt_notify(struct proto *P, struct channel *ch UNUSED, const net_addr *net,
krt_replace_rte(p, net, new, old); krt_replace_rte(p, net, new, old);
break; break;
case KPS_FLUSHING:
/* Drop any incoming route */
krt_replace_rte(p, net, NULL, old ?: new);
} }
} }
@ -768,11 +758,6 @@ krt_export_fed(struct channel *C)
p->sync_state = KPS_IDLE; p->sync_state = KPS_IDLE;
break; break;
case KPS_FLUSHING:
krt_do_scan(p);
krt_cleanup(p);
proto_notify_state(&p->p, PS_DOWN);
return;
} }
} }
@ -896,17 +881,34 @@ krt_shutdown(struct proto *P)
/* FIXME we should flush routes even when persist during reconfiguration */ /* FIXME we should flush routes even when persist during reconfiguration */
if (p->initialized && !KRT_CF->persist && (P->down_code != PDC_CMD_GR_DOWN)) if (p->initialized && !KRT_CF->persist && (P->down_code != PDC_CMD_GR_DOWN))
{ {
p->sync_state = KPS_FLUSHING; struct rt_export_feeder req = (struct rt_export_feeder)
channel_request_full_refeed(p->p.main_channel); {
.name = "shutdown.feeder",
.trace_routes = P->main_channel->debug,
};
rt_feeder_subscribe(&P->main_channel->table->export_best, &req);
/* Keeping the protocol UP until the feed-to-flush is done */ RT_FEED_WALK(&req, f)
return PS_UP; {
for (uint i = 0; i < f->count_routes; i++)
{
rte *e = &f->block[i];
if (bmap_test(&P->main_channel->export_rejected_map, e->id))
continue;
/* if exported then delete from kernel */
krt_replace_rte(p, e->net, NULL, e);
}
}
krt_do_scan(p);
krt_cleanup(p);
proto_notify_state(&p->p, PS_DOWN);
rt_feeder_unsubscribe(&req);
} }
else else
{
krt_cleanup(p); krt_cleanup(p);
return PS_DOWN; return PS_DOWN;
}
} }
static void static void

View File

@ -66,7 +66,6 @@ struct krt_proto {
KPS_IDLE, KPS_IDLE,
KPS_SCANNING, KPS_SCANNING,
KPS_PRUNING, KPS_PRUNING,
KPS_FLUSHING,
} sync_state; /* What is happening with the table sync routine */ } sync_state; /* What is happening with the table sync routine */
}; };