I found it. ugh. storing the dynamically aquired SPIs in a struct the gets overwritten was no good idea - of course we fail to reove the old SPIs then on reconfig.
to get your box going again, reconfig bgpd with new passwords, flush the SAs using ipsecctl (will kill existing md5'd sessions), and clear the session then. that means, you need to delete the old SAs before re-establishing the session, that is the bug. the diff below fixes the issue in bgpd. Index: pfkey.c =================================================================== RCS file: /cvs/src/usr.sbin/bgpd/pfkey.c,v retrieving revision 1.32 diff -u -p -r1.32 pfkey.c --- pfkey.c 30 Aug 2006 17:58:40 -0000 1.32 +++ pfkey.c 26 Oct 2006 11:42:36 -0000 @@ -497,34 +497,34 @@ pfkey_sa_remove(struct bgpd_addr *src, s int pfkey_md5sig_establish(struct peer *p) { - if (!p->conf.auth.spi_out) + if (!p->auth.spi_out) if (pfkey_sa_add(&p->conf.local_addr, &p->conf.remote_addr, p->conf.auth.md5key_len, p->conf.auth.md5key, - &p->conf.auth.spi_out) == -1) + &p->auth.spi_out) == -1) return (-1); - if (!p->conf.auth.spi_in) + if (!p->auth.spi_in) if (pfkey_sa_add(&p->conf.remote_addr, &p->conf.local_addr, p->conf.auth.md5key_len, p->conf.auth.md5key, - &p->conf.auth.spi_in) == -1) + &p->auth.spi_in) == -1) return (-1); - p->auth_established = 1; + p->auth.established = 1; return (0); } int pfkey_md5sig_remove(struct peer *p) { - if (p->conf.auth.spi_out) + if (p->auth.spi_out) if (pfkey_sa_remove(&p->conf.local_addr, &p->conf.remote_addr, - &p->conf.auth.spi_out) == -1) + &p->auth.spi_out) == -1) return (-1); - if (p->conf.auth.spi_in) + if (p->auth.spi_in) if (pfkey_sa_remove(&p->conf.remote_addr, &p->conf.local_addr, - &p->conf.auth.spi_in) == -1) + &p->auth.spi_in) == -1) return (-1); - p->auth_established = 0; + p->auth.established = 0; return (0); } @@ -597,7 +597,7 @@ pfkey_ipsec_establish(struct peer *p) if (pfkey_reply(fd, NULL) < 0) return (-1); - p->auth_established = 1; + p->auth.established = 1; return (0); } @@ -662,7 +662,7 @@ pfkey_ipsec_remove(struct peer *p) if (pfkey_reply(fd, NULL) < 0) return (-1); - p->auth_established = 0; + p->auth.established = 0; return (0); } @@ -680,7 +680,7 @@ pfkey_establish(struct peer *p) int pfkey_remove(struct peer *p) { - if (!p->auth_established) + if (!p->auth.established) return (0); else if (p->conf.auth.method == AUTH_MD5SIG) return (pfkey_md5sig_remove(p)); Index: session.h =================================================================== RCS file: /cvs/src/usr.sbin/bgpd/session.h,v retrieving revision 1.86 diff -u -p -r1.86 session.h --- session.h 27 Aug 2006 16:11:05 -0000 1.86 +++ session.h 26 Oct 2006 11:42:36 -0000 @@ -166,6 +166,11 @@ struct peer { struct capabilities ann; struct capabilities peer; } capa; + struct { + u_int32_t spi_in; + u_int32_t spi_out; + u_int8_t established; + } auth; struct sockaddr_storage sa_local; struct sockaddr_storage sa_remote; struct msgbuf wbuf; @@ -184,7 +189,6 @@ struct peer { enum session_state state; enum session_state prev_state; u_int16_t holdtime; - u_int8_t auth_established; u_int8_t depend_ok; u_int8_t demoted; u_int8_t passive;