summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorClaudio Jeker <claudio@cvs.openbsd.org>2015-06-21 12:16:30 +0000
committerClaudio Jeker <claudio@cvs.openbsd.org>2015-06-21 12:16:30 +0000
commitfcbe0144a9d84344101b85e0e75c55c48c3aedec (patch)
treed2f47138a35d8a7c372401e7e4167d2aea4e139a
parent21b29d8136604b9cb75567326275572803aec0f2 (diff)
There is a race between sending notifications to the SE and getting a new
peer_up event in the RDE. This can be triggered by graceful restart. So remove the panic and replace it with roughly what peer_down does. OK phessler and henning
-rw-r--r--usr.sbin/bgpd/rde.c17
1 files changed, 14 insertions, 3 deletions
diff --git a/usr.sbin/bgpd/rde.c b/usr.sbin/bgpd/rde.c
index fea40aef92a..8bc792566d9 100644
--- a/usr.sbin/bgpd/rde.c
+++ b/usr.sbin/bgpd/rde.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rde.c,v 1.331 2015/06/19 14:54:12 phessler Exp $ */
+/* $OpenBSD: rde.c,v 1.332 2015/06/21 12:16:29 claudio Exp $ */
/*
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -3190,8 +3190,19 @@ peer_up(u_int32_t id, struct session_up *sup)
}
if (peer->state != PEER_DOWN && peer->state != PEER_NONE &&
- peer->state != PEER_UP)
- fatalx("peer_up: bad state");
+ peer->state != PEER_UP) {
+ /*
+ * There is a race condition when doing PEER_ERR -> PEER_DOWN.
+ * So just do a full reset of the peer here.
+ */
+ for (i = 0; i < AID_MAX; i++) {
+ peer->staletime[i] = 0;
+ peer_flush(peer, i);
+ }
+ up_down(peer);
+ peer->prefix_cnt = 0;
+ peer->state = PEER_DOWN;
+ }
peer->remote_bgpid = ntohl(sup->remote_bgpid);
peer->short_as = sup->short_as;
memcpy(&peer->remote_addr, &sup->remote_addr,