diff options
author | Claudio Jeker <claudio@cvs.openbsd.org> | 2022-03-01 09:53:43 +0000 |
---|---|---|
committer | Claudio Jeker <claudio@cvs.openbsd.org> | 2022-03-01 09:53:43 +0000 |
commit | 03f78236db966b452407fb0b5cc25fa3f563e03b (patch) | |
tree | e71fd530c282e6f3b5cdfe71b0dddc3e17439c61 | |
parent | 1b9db8b25c7ec2f1b081bcc9dc627b211b0aacc7 (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.c | 9 |
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++; } |