diff options
-rw-r--r-- | usr.sbin/bgpd/session.c | 18 | ||||
-rw-r--r-- | usr.sbin/bgpd/session.h | 4 |
2 files changed, 16 insertions, 6 deletions
diff --git a/usr.sbin/bgpd/session.c b/usr.sbin/bgpd/session.c index c6fdc57e90c..4901d585f5c 100644 --- a/usr.sbin/bgpd/session.c +++ b/usr.sbin/bgpd/session.c @@ -1,4 +1,4 @@ -/* $OpenBSD: session.c,v 1.233 2005/09/08 10:46:40 henning Exp $ */ +/* $OpenBSD: session.c,v 1.234 2005/09/19 16:15:54 henning Exp $ */ /* * Copyright (c) 2003, 2004, 2005 Henning Brauer <henning@openbsd.org> @@ -379,6 +379,7 @@ session_main(struct bgpd_config *config, struct peer *cpeers, p->IdleHoldTime = INTERVAL_IDLE_HOLD_INITIAL; p->IdleHoldResetTimer = 0; + p->errcnt = 0; } else p->IdleHoldResetTimer = time(NULL) + p->IdleHoldTime; @@ -579,7 +580,8 @@ bgp_fsm(struct peer *peer, enum session_events event) if (!peer->depend_ok) peer->ConnectRetryTimer = 0; - else if (peer->conf.passive || peer->conf.template) { + else if (peer->passive || peer->conf.passive || + peer->conf.template) { change_state(peer, STATE_ACTIVE, event); peer->ConnectRetryTimer = 0; } else { @@ -588,6 +590,7 @@ bgp_fsm(struct peer *peer, enum session_events event) time(NULL) + INTERVAL_CONNECTRETRY; session_connect(peer); } + peer->passive = 0; break; default: /* ignore */ @@ -870,9 +873,7 @@ change_state(struct peer *peer, enum session_state state, case STATE_OPENCONFIRM: break; case STATE_ESTABLISHED: - if (peer->IdleHoldTime > INTERVAL_IDLE_HOLD_INITIAL) - peer->IdleHoldResetTimer = - time(NULL) + peer->IdleHoldTime; + peer->IdleHoldResetTimer = time(NULL) + peer->IdleHoldTime; session_up(peer); break; default: /* something seriously fucked */ @@ -913,6 +914,12 @@ session_accept(int listenfd) p = getpeerbyip((struct sockaddr *)&cliaddr); + if (p != NULL && p->state == STATE_IDLE && p->errcnt < 2) { + /* fast reconnect after clear */ + p->passive = 1; + bgp_fsm(p, EVNT_START); + } + if (p != NULL && (p->state == STATE_CONNECT || p->state == STATE_ACTIVE)) { if (p->fd != -1) { @@ -1916,6 +1923,7 @@ parse_notification(struct peer *peer) datalen -= sizeof(subcode); log_notification(peer, errcode, subcode, p, datalen); + peer->errcnt++; if (errcode == ERR_OPEN && subcode == ERR_OPEN_CAPA) { if (datalen == 0) { /* zebra likes to send those.. humbug */ diff --git a/usr.sbin/bgpd/session.h b/usr.sbin/bgpd/session.h index 950aeb425ea..7f613364c72 100644 --- a/usr.sbin/bgpd/session.h +++ b/usr.sbin/bgpd/session.h @@ -1,4 +1,4 @@ -/* $OpenBSD: session.h,v 1.77 2005/06/04 22:50:20 henning Exp $ */ +/* $OpenBSD: session.h,v 1.78 2005/09/19 16:15:54 henning Exp $ */ /* * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org> @@ -168,6 +168,7 @@ struct peer { time_t IdleHoldResetTimer; int fd; int lasterr; + u_int errcnt; u_int IdleHoldTime; u_int32_t remote_bgpid; enum session_state state; @@ -175,6 +176,7 @@ struct peer { u_int16_t holdtime; u_int8_t auth_established; u_int8_t depend_ok; + u_int8_t passive; }; struct peer *peers; |