Date: Wed, 3 Sep 2003 21:27:48 -0700 (PDT) From: Sam Leffler <sam@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 37476 for review Message-ID: <200309040427.h844RmdQ058556@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=37476 Change 37476 by sam@sam_ebb on 2003/09/03 21:27:48 rtrequest(RTM_DELETE, ...) locks the rtentry found by looking up the destination address that's specified. This means the caller cannot be holding a locked reference when doing this operation so (for now) drop the lock and reaquire it after the delete. Various alternatives were considered, including adding a delete interface that takes a locked rtentry, but none are as clean as this. It appears that dropping+reacquiring the lock is safe in all these cases. This problem appeared when ejecting a cardbus network card configured with IPv6. Affected files ... .. //depot/projects/netperf/sys/netinet/in_rmx.c#4 edit .. //depot/projects/netperf/sys/netinet6/in6_ifattach.c#3 edit .. //depot/projects/netperf/sys/netinet6/in6_rmx.c#4 edit Differences ... ==== //depot/projects/netperf/sys/netinet/in_rmx.c#4 (text+ko) ==== @@ -72,7 +72,6 @@ struct sockaddr_in *sin = (struct sockaddr_in *)rt_key(rt); struct radix_node *ret; - /*XXX locking? */ /* * For IP, all unicast non-host routes are automatically cloning. */ @@ -126,12 +125,15 @@ rt2->rt_flags & RTF_HOST && rt2->rt_gateway && rt2->rt_gateway->sa_family == AF_LINK) { + /* NB: must unlock to avoid recursion */ + RT_UNLOCK(rt2); rtrequest(RTM_DELETE, (struct sockaddr *)rt_key(rt2), rt2->rt_gateway, rt_mask(rt2), rt2->rt_flags, 0); ret = rn_addroute(v_arg, n_arg, head, treenodes); + RT_LOCK(rt2); } RTFREE_LOCKED(rt2); } @@ -212,10 +214,13 @@ rt->rt_flags |= RTPRF_OURS; rt->rt_rmx.rmx_expire = time_second + rtq_reallyold; } else { + /* NB: must unlock to avoid recursion */ + RT_UNLOCK(rt); rtrequest(RTM_DELETE, (struct sockaddr *)rt_key(rt), rt->rt_gateway, rt_mask(rt), rt->rt_flags, 0); + RT_LOCK(rt); } } ==== //depot/projects/netperf/sys/netinet6/in6_ifattach.c#3 (text+ko) ==== @@ -986,10 +986,13 @@ sin6.sin6_addr.s6_addr16[1] = htons(ifp->if_index); rt = rtalloc1((struct sockaddr *)&sin6, 0, 0UL); if (rt) { - if (rt->rt_ifp == ifp) + if (rt->rt_ifp == ifp) { + RT_UNLOCK(rt); rtrequest(RTM_DELETE, (struct sockaddr *)rt_key(rt), rt->rt_gateway, rt_mask(rt), rt->rt_flags, 0); - rtfree(rt); + RTFREE(rt); + } else + rtfree(rt); } } ==== //depot/projects/netperf/sys/netinet6/in6_rmx.c#4 (text+ko) ==== @@ -166,12 +166,15 @@ rt2->rt_flags & RTF_HOST && rt2->rt_gateway && rt2->rt_gateway->sa_family == AF_LINK) { + /* NB: must unlock to avoid recursion */ + RT_UNLOCK(rt2); rtrequest(RTM_DELETE, (struct sockaddr *)rt_key(rt2), rt2->rt_gateway, rt_mask(rt2), rt2->rt_flags, 0); ret = rn_addroute(v_arg, n_arg, head, treenodes); + RT_LOCK(rt2); } RTFREE_LOCKED(rt2); } @@ -272,10 +275,13 @@ rt->rt_flags |= RTPRF_OURS; rt->rt_rmx.rmx_expire = time_second + rtq_reallyold; } else { + /* NB: must unlock to avoid recursion */ + RT_UNLOCK(rt); rtrequest(RTM_DELETE, (struct sockaddr *)rt_key(rt), rt->rt_gateway, rt_mask(rt), rt->rt_flags, 0); + RT_LOCK(rt); } }
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200309040427.h844RmdQ058556>