summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorClaudio Jeker <claudio@cvs.openbsd.org>2022-03-01 09:53:43 +0000
committerClaudio Jeker <claudio@cvs.openbsd.org>2022-03-01 09:53:43 +0000
commit03f78236db966b452407fb0b5cc25fa3f563e03b (patch)
treee71fd530c282e6f3b5cdfe71b0dddc3e17439c61
parent1b9db8b25c7ec2f1b081bcc9dc627b211b0aacc7 (diff)
up_dump_prefix() should not clear the p->flags before possibly calling
prefix_adjout_destroy(). Doing so will restult in a double pt_unref() call because prefix_adjout_destroy() no longer notices that the prefix was an actuall withdraw and wrongly calls prefix_unlink(). For updates the PREFIX_FLAG_UPDATE flag needs to be cleared after removing the prefix from the update RB tree. Adjust the EoR codepath in a similar way. EoR have a NULL pt_entry and so prefix_adjout_destroy() is unable to do the RB_REMOVE. This fixes the regress errors reported by anton@ OK tb@
-rw-r--r--usr.sbin/bgpd/rde_update.c9
1 files changed, 4 insertions, 5 deletions
diff --git a/usr.sbin/bgpd/rde_update.c b/usr.sbin/bgpd/rde_update.c
index 15d5b052260..d8460f8f6ef 100644
--- a/usr.sbin/bgpd/rde_update.c
+++ b/usr.sbin/bgpd/rde_update.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rde_update.c,v 1.133 2022/02/24 14:54:03 claudio Exp $ */
+/* $OpenBSD: rde_update.c,v 1.134 2022/03/01 09:53:42 claudio Exp $ */
/*
* Copyright (c) 2004 Claudio Jeker <claudio@openbsd.org>
@@ -605,7 +605,7 @@ up_is_eor(struct rde_peer *peer, uint8_t aid)
* prefix_adjout_destroy() can't handle that.
*/
RB_REMOVE(prefix_tree, &peer->updates[aid], p);
- p->flags &= ~PREFIX_FLAG_MASK;
+ p->flags &= ~PREFIX_FLAG_UPDATE;
prefix_adjout_destroy(p);
return 1;
}
@@ -651,9 +651,6 @@ up_dump_prefix(u_char *buf, int len, struct prefix_tree *prefix_head,
np->eor)
done = 1;
- /* prefix sent, remove from list and clear flag */
- RB_REMOVE(prefix_tree, prefix_head, p);
- p->flags &= ~PREFIX_FLAG_MASK;
if (withdraw) {
/* prefix no longer needed, remove it */
@@ -662,6 +659,8 @@ up_dump_prefix(u_char *buf, int len, struct prefix_tree *prefix_head,
peer->prefix_sent_withdraw++;
} else {
/* prefix still in Adj-RIB-Out, keep it */
+ RB_REMOVE(prefix_tree, prefix_head, p);
+ p->flags &= ~PREFIX_FLAG_UPDATE;
peer->up_nlricnt--;
peer->prefix_sent_update++;
}