diff options
author | Henning Brauer <henning@cvs.openbsd.org> | 2006-04-12 14:23:47 +0000 |
---|---|---|
committer | Henning Brauer <henning@cvs.openbsd.org> | 2006-04-12 14:23:47 +0000 |
commit | 2c43e10447b25d91e0c1157699481bdd35ec78f7 (patch) | |
tree | 618009d431a56d5b11c7c73e957296689331daf1 | |
parent | 58d46986875974ae3498c270d878b3d6309c8f23 (diff) |
messages on the routing socket have different headers - rt_msghdr,
if_msghdr, etc. they only share the first 3 fields, and then differ.
this leads to a bug in RTM_IFINFO handling. We did abort on
rtm->rtm_errno != 0,
but if_msghdr has no errno, so we look at something in the data part
instead. Surprising that this didn't bite us before!
So we must only do these checks for RTM_ADD/CHANGE/DELETE that actually
use rt_msghdr.
found whiel checking strange behaviour tony sarendal <dualcyclone@gmail.com>
saw, and then totally strange behaviour on my amd64 hackbox. claudio ok
-rw-r--r-- | usr.sbin/bgpd/kroute.c | 20 |
1 files changed, 11 insertions, 9 deletions
diff --git a/usr.sbin/bgpd/kroute.c b/usr.sbin/bgpd/kroute.c index c16404e0909..b7b45d2ac69 100644 --- a/usr.sbin/bgpd/kroute.c +++ b/usr.sbin/bgpd/kroute.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kroute.c,v 1.145 2006/03/22 13:30:35 claudio Exp $ */ +/* $OpenBSD: kroute.c,v 1.146 2006/04/12 14:23:46 henning Exp $ */ /* * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org> @@ -2123,21 +2123,23 @@ dispatch_rtmsg(void) lim = buf + n; for (next = buf; next < lim; next += rtm->rtm_msglen) { rtm = (struct rt_msghdr *)next; - sa = (struct sockaddr *)(rtm + 1); - get_rtaddrs(rtm->rtm_addrs, sa, rti_info); - - if (rtm->rtm_pid == kr_state.pid) /* cause by us */ - continue; - - if (rtm->rtm_errno) /* failed attempts... */ - continue; switch (rtm->rtm_type) { case RTM_ADD: case RTM_CHANGE: case RTM_DELETE: + sa = (struct sockaddr *)(rtm + 1); + get_rtaddrs(rtm->rtm_addrs, sa, rti_info); + + if (rtm->rtm_pid == kr_state.pid) /* cause by us */ + continue; + + if (rtm->rtm_errno) /* failed attempts... */ + continue; + if (rtm->rtm_flags & RTF_LLINFO) /* arp cache */ continue; + if (dispatch_rtmsg_addr(rtm, rti_info) == -1) return (-1); break; |