In the first few error cases where pfkey_reply returns early, shouldn't the pending message still at least be read off the socket? E.g., right now (as far as I can tell), if a pfkey response packet ever has sadb_msg_errno set, that response will stay on the socket forever and be used for every future pfkey_reply call.
Patch below is completely untested, and just meant to help explain the potential problem. I'm assuming that pfkey sockets behave like udp sockets, and that reads without enough space still consume an entire datagram. Index: pfkey.c =================================================================== RCS file: /cvs/src/usr.sbin/bgpd/pfkey.c,v retrieving revision 1.34 diff -p -u -r1.34 pfkey.c --- pfkey.c 26 Oct 2006 14:26:49 -0000 1.34 +++ pfkey.c 17 Apr 2009 20:11:38 -0000 @@ -417,9 +417,11 @@ pfkey_reply(int sd, u_int32_t *spip) if (recv(sd, &hdr, sizeof(hdr), MSG_PEEK) != sizeof(hdr)) { log_warn("pfkey peek"); + read(sd, &hdr, sizeof(hdr)); /* discard packet */ return (-1); } if (hdr.sadb_msg_errno != 0) { + read(sd, &hdr, sizeof(hdr)); /* discard packet */ errno = hdr.sadb_msg_errno; if (errno == ESRCH) return (0); @@ -431,6 +433,7 @@ pfkey_reply(int sd, u_int32_t *spip) len = hdr.sadb_msg_len * PFKEY2_CHUNK; if ((data = malloc(len)) == NULL) { log_warn("pfkey malloc"); + read(sd, &hdr, sizeof(hdr)); /* discard packet */ return (-1); } if (read(sd, data, len) != len) {