-/* $OpenBSD: rde.c,v 1.538 2022/02/28 12:52:38 claudio Exp $ */
+/* $OpenBSD: rde.c,v 1.539 2022/03/02 14:44:46 claudio Exp $ */
/*
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
static void
rde_up_flush_upcall(struct prefix *p, void *ptr)
{
- struct rde_peer *peer = ptr;
-
- up_generate_updates(out_rules, peer, NULL, p);
+ prefix_adjout_withdraw(p);
}
u_char queue_buf[4096];
if (peer->reconf_rib) {
if (prefix_dump_new(peer, AID_UNSPEC,
- RDE_RUNNER_ROUNDS, peer, rde_up_flush_upcall,
+ RDE_RUNNER_ROUNDS, NULL, rde_up_flush_upcall,
rde_softreconfig_in_done, NULL) == -1)
fatal("%s: prefix_dump_new", __func__);
log_peer_info(&peer->conf, "flushing Adj-RIB-Out");
-/* $OpenBSD: rde.h,v 1.244 2022/02/25 11:36:54 claudio Exp $ */
+/* $OpenBSD: rde.h,v 1.245 2022/03/02 14:44:46 claudio Exp $ */
/*
* Copyright (c) 2003, 2004 Claudio Jeker <claudio@openbsd.org> and
void prefix_add_eor(struct rde_peer *, uint8_t);
int prefix_adjout_update(struct rde_peer *, struct filterstate *,
struct bgpd_addr *, int, uint8_t);
-int prefix_adjout_withdraw(struct rde_peer *, struct bgpd_addr *,
- int);
+void prefix_adjout_withdraw(struct prefix *);
void prefix_adjout_destroy(struct prefix *p);
void prefix_adjout_dump(struct rde_peer *, void *,
void (*)(struct prefix *, void *));
-/* $OpenBSD: rde_rib.c,v 1.230 2022/03/01 09:39:36 claudio Exp $ */
+/* $OpenBSD: rde_rib.c,v 1.231 2022/03/02 14:44:46 claudio Exp $ */
/*
* Copyright (c) 2003, 2004 Claudio Jeker <claudio@openbsd.org>
* Withdraw a prefix from the Adj-RIB-Out, this unlinks the aspath but leaves
* the prefix in the RIB linked to the peer withdraw list.
*/
-int
-prefix_adjout_withdraw(struct rde_peer *peer, struct bgpd_addr *prefix,
- int prefixlen)
+void
+prefix_adjout_withdraw(struct prefix *p)
{
- struct prefix *p;
-
- p = prefix_adjout_get(peer, 0, prefix, prefixlen);
- if (p == NULL) /* Got a dummy withdrawn request. */
- return (0);
+ struct rde_peer *peer = prefix_peer(p);
if ((p->flags & PREFIX_FLAG_ADJOUT) == 0)
fatalx("%s: prefix without PREFIX_FLAG_ADJOUT hit", __func__);
- /* already a withdraw, error */
- if (p->flags & PREFIX_FLAG_WITHDRAW)
- log_warnx("%s: prefix already withdrawed", __func__);
+ /* already a withdraw, shortcut */
+ if (p->flags & PREFIX_FLAG_WITHDRAW) {
+ p->lastchange = getmonotime();
+ p->flags &= ~PREFIX_FLAG_STALE;
+ return;
+ }
/* pending update just got withdrawn */
- if (p->flags & PREFIX_FLAG_UPDATE)
+ if (p->flags & PREFIX_FLAG_UPDATE) {
RB_REMOVE(prefix_tree, &peer->updates[p->pt->aid], p);
+ peer->up_nlricnt--;
+ }
/* unlink prefix if it was linked (not a withdraw or dead) */
- if ((p->flags & (PREFIX_FLAG_WITHDRAW | PREFIX_FLAG_DEAD)) == 0)
+ if ((p->flags & (PREFIX_FLAG_WITHDRAW | PREFIX_FLAG_DEAD)) == 0) {
prefix_unlink(p);
+ peer->prefix_out_cnt--;
+ }
/* nothing needs to be done for PREFIX_FLAG_DEAD and STALE */
p->flags &= ~PREFIX_FLAG_MASK;
p->lastchange = getmonotime();
p->flags |= PREFIX_FLAG_WITHDRAW;
- if (RB_INSERT(prefix_tree, &peer->withdraws[prefix->aid], p) != NULL)
+ if (RB_INSERT(prefix_tree, &peer->withdraws[p->pt->aid], p) != NULL)
fatalx("%s: RB tree invariant violated", __func__);
- return (1);
+
+ peer->up_wcnt++;
}
void
return;
}
- if (p->flags & PREFIX_FLAG_WITHDRAW)
+ if (p->flags & PREFIX_FLAG_WITHDRAW) {
RB_REMOVE(prefix_tree, &peer->withdraws[p->pt->aid], p);
- if (p->flags & PREFIX_FLAG_UPDATE)
+ peer->up_wcnt--;
+ }
+ if (p->flags & PREFIX_FLAG_UPDATE) {
RB_REMOVE(prefix_tree, &peer->updates[p->pt->aid], p);
+ peer->up_nlricnt--;
+ }
/* unlink prefix if it was linked (not a withdraw or dead) */
- if ((p->flags & (PREFIX_FLAG_WITHDRAW | PREFIX_FLAG_DEAD)) == 0)
+ if ((p->flags & (PREFIX_FLAG_WITHDRAW | PREFIX_FLAG_DEAD)) == 0) {
prefix_unlink(p);
+ peer->prefix_out_cnt--;
+ }
/* nothing needs to be done for PREFIX_FLAG_DEAD and STALE */
p->flags &= ~PREFIX_FLAG_MASK;
-/* $OpenBSD: rde_update.c,v 1.134 2022/03/01 09:53:42 claudio Exp $ */
+/* $OpenBSD: rde_update.c,v 1.135 2022/03/02 14:44:46 claudio Exp $ */
/*
* Copyright (c) 2004 Claudio Jeker <claudio@openbsd.org>
{
struct filterstate state;
struct bgpd_addr addr;
+ struct prefix *p;
int need_withdraw;
uint8_t prefixlen;
again:
if (new == NULL) {
/* withdraw prefix */
- if (prefix_adjout_withdraw(peer, &addr, prefixlen) == 1) {
- peer->prefix_out_cnt--;
- peer->up_wcnt++;
- }
+ if ((p = prefix_adjout_get(peer, 0, &addr, prefixlen)) != NULL)
+ prefix_adjout_withdraw(p);
} else {
need_withdraw = 0;
/*
if (withdraw) {
/* prefix no longer needed, remove it */
prefix_adjout_destroy(p);
- peer->up_wcnt--;
peer->prefix_sent_withdraw++;
} else {
/* prefix still in Adj-RIB-Out, keep it */