-/* $OpenBSD: rde.c,v 1.564 2022/08/17 15:15:26 claudio Exp $ */
+/* $OpenBSD: rde.c,v 1.565 2022/08/26 14:10:52 claudio Exp $ */
/*
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
{
struct imsg imsg;
struct peer p;
- struct peer_config pconf;
struct ctl_show_set cset;
struct ctl_show_rib csr;
struct ctl_show_rib_request req;
+ struct session_up sup;
struct rde_peer *peer;
struct rde_aspath *asp;
struct rde_hashstats rdehash;
size_t aslen;
int verbose;
uint16_t len;
+ uint8_t aid;
while (ibuf) {
if ((n = imsg_get(ibuf, &imsg)) == -1)
switch (imsg.hdr.type) {
case IMSG_UPDATE:
- case IMSG_SESSION_UP:
- case IMSG_SESSION_DOWN:
- case IMSG_SESSION_STALE:
- case IMSG_SESSION_FLUSH:
- case IMSG_SESSION_RESTARTED:
case IMSG_REFRESH:
if ((peer = peer_get(imsg.hdr.peerid)) == NULL) {
log_warnx("rde_dispatch: unknown peer id %d",
peer_imsg_push(peer, &imsg);
break;
case IMSG_SESSION_ADD:
- if (imsg.hdr.len - IMSG_HEADER_SIZE != sizeof(pconf))
+ if (imsg.hdr.len - IMSG_HEADER_SIZE !=
+ sizeof(struct peer_config))
+ fatalx("incorrect size of session request");
+ peer = peer_add(imsg.hdr.peerid, imsg.data);
+ /* make sure rde_eval_all is on if needed. */
+ if (peer->conf.flags & PEERFLAG_EVALUATE_ALL)
+ rde_eval_all = 1;
+ break;
+ case IMSG_SESSION_UP:
+ if ((peer = peer_get(imsg.hdr.peerid)) == NULL) {
+ log_warnx("%s: unknown peer id %d",
+ "IMSG_SESSION_UP", imsg.hdr.peerid);
+ break;
+ }
+ if (imsg.hdr.len - IMSG_HEADER_SIZE != sizeof(sup))
fatalx("incorrect size of session request");
- memcpy(&pconf, imsg.data, sizeof(pconf));
- peer_add(imsg.hdr.peerid, &pconf);
+ memcpy(&sup, imsg.data, sizeof(sup));
+ peer_up(peer, &sup);
/* make sure rde_eval_all is on if needed. */
- if (pconf.flags & PEERFLAG_EVALUATE_ALL)
+ if (peer_has_add_path(peer, AID_UNSPEC, CAPA_AP_SEND))
rde_eval_all = 1;
break;
+ case IMSG_SESSION_DOWN:
+ if ((peer = peer_get(imsg.hdr.peerid)) == NULL) {
+ log_warnx("%s: unknown peer id %d",
+ "IMSG_SESSION_DOWN", imsg.hdr.peerid);
+ break;
+ }
+ peer_down(peer, NULL);
+ break;
+ case IMSG_SESSION_STALE:
+ case IMSG_SESSION_NOGRACE:
+ case IMSG_SESSION_FLUSH:
+ case IMSG_SESSION_RESTARTED:
+ if ((peer = peer_get(imsg.hdr.peerid)) == NULL) {
+ log_warnx("%s: unknown peer id %d",
+ "graceful restart", imsg.hdr.peerid);
+ break;
+ }
+ if (imsg.hdr.len - IMSG_HEADER_SIZE != sizeof(aid)) {
+ log_warnx("%s: wrong imsg len", __func__);
+ break;
+ }
+ memcpy(&aid, imsg.data, sizeof(aid));
+ if (aid >= AID_MAX) {
+ log_warnx("%s: bad AID", __func__);
+ break;
+ }
+
+ switch (imsg.hdr.type) {
+ case IMSG_SESSION_STALE:
+ case IMSG_SESSION_NOGRACE:
+ peer_stale(peer, aid,
+ imsg.hdr.type == IMSG_SESSION_NOGRACE);
+ break;
+ case IMSG_SESSION_FLUSH:
+ peer_flush(peer, aid, peer->staletime[aid]);
+ break;
+ case IMSG_SESSION_RESTARTED:
+ if (peer->staletime[aid])
+ peer_flush(peer, aid,
+ peer->staletime[aid]);
+ break;
+ }
+ break;
case IMSG_NETWORK_ADD:
if (imsg.hdr.len - IMSG_HEADER_SIZE !=
sizeof(struct network_config)) {
rde_dispatch_imsg_peer(struct rde_peer *peer, void *bula)
{
struct route_refresh rr;
- struct session_up sup;
struct imsg imsg;
- uint8_t aid;
if (!peer_imsg_pop(peer, &imsg))
return;
break;
rde_update_dispatch(peer, &imsg);
break;
- case IMSG_SESSION_UP:
- if (imsg.hdr.len - IMSG_HEADER_SIZE != sizeof(sup))
- fatalx("incorrect size of session request");
- memcpy(&sup, imsg.data, sizeof(sup));
- if (peer_up(peer, &sup) == -1) {
- peer->state = PEER_DOWN;
- imsg_compose(ibuf_se, IMSG_SESSION_DOWN, peer->conf.id,
- 0, -1, NULL, 0);
- }
- /* make sure rde_eval_all is on if needed. */
- if (peer_has_add_path(peer, AID_UNSPEC, CAPA_AP_SEND))
- rde_eval_all = 1;
- break;
- case IMSG_SESSION_DOWN:
- peer_down(peer, NULL);
- break;
- case IMSG_SESSION_STALE:
- case IMSG_SESSION_FLUSH:
- case IMSG_SESSION_RESTARTED:
- if (imsg.hdr.len - IMSG_HEADER_SIZE != sizeof(aid)) {
- log_warnx("%s: wrong imsg len", __func__);
- break;
- }
- memcpy(&aid, imsg.data, sizeof(aid));
- if (aid >= AID_MAX) {
- log_warnx("%s: bad AID", __func__);
- break;
- }
-
- switch (imsg.hdr.type) {
- case IMSG_SESSION_STALE:
- peer_stale(peer, aid);
- break;
- case IMSG_SESSION_FLUSH:
- peer_flush(peer, aid, peer->staletime[aid]);
- break;
- case IMSG_SESSION_RESTARTED:
- if (peer->staletime[aid])
- peer_flush(peer, aid, peer->staletime[aid]);
- break;
- }
- break;
case IMSG_REFRESH:
if (imsg.hdr.len - IMSG_HEADER_SIZE != sizeof(rr)) {
log_warnx("route refresh: wrong imsg len");
-/* $OpenBSD: rde_peer.c,v 1.21 2022/08/17 15:15:26 claudio Exp $ */
+/* $OpenBSD: rde_peer.c,v 1.22 2022/08/26 14:10:52 claudio Exp $ */
/*
* Copyright (c) 2019 Claudio Jeker <claudio@openbsd.org>
pc.id = PEER_ID_SELF;
peerself = peer_add(PEER_ID_SELF, &pc);
- if (peerself == NULL)
- fatalx("peer_init add self");
-
peerself->state = PEER_UP;
}
if ((peer = peer_get(id))) {
memcpy(&peer->conf, p_conf, sizeof(struct peer_config));
- return (NULL);
+ return (peer);
}
peer = calloc(1, sizeof(struct rde_peer));
/*
* Session got established, bring peer up, load RIBs do initial table dump.
*/
-int
+void
peer_up(struct rde_peer *peer, struct session_up *sup)
{
uint8_t i;
* There is a race condition when doing PEER_ERR -> PEER_DOWN.
* So just do a full reset of the peer here.
*/
+ rib_dump_terminate(peer);
+ peer_imsg_flush(peer);
if (prefix_dump_new(peer, AID_UNSPEC, 0, NULL,
peer_adjout_clear_upcall, NULL, NULL) == -1)
fatal("%s: prefix_dump_new", __func__);
if (peer->capa.mp[i])
peer_dump(peer, i);
}
-
- return (0);
}
/*
{
peer->remote_bgpid = 0;
peer->state = PEER_DOWN;
- /* stop all pending dumps which may depend on this peer */
+ /*
+ * stop all pending dumps which may depend on this peer
+ * and flush all pending imsg from the SE.
+ */
rib_dump_terminate(peer);
+ peer_imsg_flush(peer);
/* flush Adj-RIB-Out */
if (prefix_dump_new(peer, AID_UNSPEC, 0, NULL,
peer->prefix_cnt = 0;
peer->prefix_out_cnt = 0;
- peer_imsg_flush(peer);
-
LIST_REMOVE(peer, hash_l);
LIST_REMOVE(peer, peer_l);
free(peer);
* is set to the current timestamp for identifying stale routes in Adj-RIB-In.
*/
void
-peer_stale(struct rde_peer *peer, uint8_t aid)
+peer_stale(struct rde_peer *peer, uint8_t aid, int flushall)
{
time_t now;
peer->staletime[aid] = now = getmonotime();
peer->state = PEER_DOWN;
+ /*
+ * stop all pending dumps which may depend on this peer
+ * and flush all pending imsg from the SE.
+ */
+ rib_dump_terminate(peer);
+ peer_imsg_flush(peer);
+
+ if (flushall)
+ peer_flush(peer, aid, 0);
+
/* XXX this is not quite correct */
/* mark Adj-RIB-Out stale for this peer */
- if (prefix_dump_new(peer, AID_UNSPEC, 0, NULL,
+ if (prefix_dump_new(peer, aid, 0, NULL,
peer_adjout_stale_upcall, NULL, NULL) == -1)
fatal("%s: prefix_dump_new", __func__);