diff options
author | 2019-06-24 22:26:25 +0000 | |
---|---|---|
committer | 2019-06-24 22:26:25 +0000 | |
commit | 9d75efe80b284884ff5139dd91fb99f7d39f486d (patch) | |
tree | 8d5a4389ed428c21f5c6ef7b1c5c47ec3993c832 | |
parent | Use timeout_add_sec(9) (diff) | |
download | wireguard-openbsd-9d75efe80b284884ff5139dd91fb99f7d39f486d.tar.xz wireguard-openbsd-9d75efe80b284884ff5139dd91fb99f7d39f486d.zip |
Since the recent recursion fix in rtable_walk(), deleting an interface
address could trigger the "rt->rt_ifidx == ifp->if_index" assertion.
In rtflushclone() the ifp that is passed to rtdeletemsg() has been
changed from the route interface to the ifa interface. Restore the
old behavior and get the route ifp.
found by regress/sys/netinet/carp; OK mpi@
-rw-r--r-- | sys/net/route.c | 19 |
1 files changed, 13 insertions, 6 deletions
diff --git a/sys/net/route.c b/sys/net/route.c index b87a31ab789..2cc08bbe552 100644 --- a/sys/net/route.c +++ b/sys/net/route.c @@ -1,4 +1,4 @@ -/* $OpenBSD: route.c,v 1.386 2019/06/21 17:11:42 mpi Exp $ */ +/* $OpenBSD: route.c,v 1.387 2019/06/24 22:26:25 bluhm Exp $ */ /* $NetBSD: route.c,v 1.14 1996/02/13 22:00:46 christos Exp $ */ /* @@ -156,7 +156,7 @@ void rt_timer_init(void); int rt_setgwroute(struct rtentry *, u_int); void rt_putgwroute(struct rtentry *); int rtflushclone1(struct rtentry *, void *, u_int); -int rtflushclone(struct ifnet *ifp, struct rtentry *, unsigned int); +int rtflushclone(struct rtentry *, unsigned int); int rt_ifa_purge_walker(struct rtentry *, void *, unsigned int); struct rtentry *rt_match(struct sockaddr *, uint32_t *, int, unsigned int); int rt_clone(struct rtentry **, struct sockaddr *, unsigned int); @@ -726,9 +726,10 @@ rtflushclone1(struct rtentry *rt, void *arg, u_int id) } int -rtflushclone(struct ifnet *ifp, struct rtentry *parent, unsigned int rtableid) +rtflushclone(struct rtentry *parent, unsigned int rtableid) { struct rtentry *rt = NULL; + struct ifnet *ifp; int error; #ifdef DIAGNOSTIC @@ -740,9 +741,15 @@ rtflushclone(struct ifnet *ifp, struct rtentry *parent, unsigned int rtableid) error = rtable_walk(rtableid, rt_key(parent)->sa_family, &rt, rtflushclone1, parent); if (rt != NULL && error == EEXIST) { - error = rtdeletemsg(rt, ifp, rtableid); - if (error == 0) + ifp = if_get(rt->rt_ifidx); + if (ifp == NULL) { error = EAGAIN; + } else { + error = rtdeletemsg(rt, ifp, rtableid); + if (error == 0) + error = EAGAIN; + if_put(ifp); + } } rtfree(rt); rt = NULL; @@ -791,7 +798,7 @@ rtrequest_delete(struct rt_addrinfo *info, u_int8_t prio, struct ifnet *ifp, /* Clean up any cloned children. */ if (ISSET(rt->rt_flags, RTF_CLONING)) - rtflushclone(ifp, rt, tableid); + rtflushclone(rt, tableid); rtfree(rt->rt_parent); rt->rt_parent = NULL; |