Date: Thu, 25 Jan 2007 21:37:20 +0300 From: Gleb Smirnoff <glebius@FreeBSD.org> To: "Bruce M. Simpson" <bms@FreeBSD.org> Cc: rwatson@FreeBSD.org, net@FreeBSD.org Subject: Re: rev. 1.94 of netinet/in.c broke CARP Message-ID: <20070125183720.GB7922@cell.sick.ru> In-Reply-To: <45B8EB23.705@FreeBSD.org> References: <20070125162422.GA7922@bestcom.ru> <45B8EB23.705@FreeBSD.org>
next in thread | previous in thread | raw e-mail | index | archive | help
Bruce, On Thu, Jan 25, 2007 at 05:38:43PM +0000, Bruce M. Simpson wrote: B> Gleb Smirnoff wrote: B> > I've just discovered, that revision 1.94 of in.c has broke CARP. This B> >change adds a code to in_ifdetach() that goes through the global list B> >of all multicast instances and deletes all the instances, that are B> >belonging to a particular interface. This is intended to avoid leaking B> >multicast instances. B> > B> The irony of this of course is that I was working on two separate fixes; B> one to prevent the MROUTING code panicking when an interface was B> suddenly removed, and the other to prevent the netinet ifp detach path B> from panicking in the same circumstances. B> B> These are resource leaks which have been in BSD for years and years. I B> neglected to test them *together* however; carp(4) was being used in the B> test cases for both bugs. Yes, I knew that we were leaking memory allocated for multicast purposes on interface detach. I was trying to fix this with Oleg and Yar, but failed. B> > Before this change, most of the subsystems, that allocated multicast B> >membership instances had freed is theirselves. I don't know about others, B> >but at least CARP is broken now. It attempts to free a memory, that B> >already has been freed. B> > B> I would suggest that the correct fix, for now, would be for carp(4) to B> now *not* perform its own cleanup for the IPv4 groups it joins on member B> interfaces. Unfortunately, this won't be a correct fix. In a scenario when the parent interface stays on its place, but you are creating, attaching and destroying a CARP interface, the multicast membership would not be left and memory won't be freed. So, after the following sequence ifconfig fxp0 10.0.0.1/24 ifconfig carp0 create ifconfig carp0 vhid 1 10.0.0.2/24 ifconfig carp0 destroy , we would still have a multicast membership on fxp0. B> The symptom here is that carp(4) needs to join a multicast group on its B> member interface. When the interface goes away, the group membership is B> now destroyed, at the netinet global level, by the netinet detach path B> first. B> B> However, carp(4) is keeping its own imo_membership vector of the B> addresses it joined on its member interfaces (rather than using the one B> which netinet assigns to it in its attach path), and later tries to free B> these memberships. B> B> netinet6 does not have the same problem because in6 memberships are B> reference counted. B> B> The root problem is that we should be using consistent semantics for B> both the IPv4 and IPv6 paths, and the kernel APIs where soft-ifnets B> (such as carp(4)) and routing code (such as MROUTING) need to manipulate B> multicast group memberships. Looks like we need refcounting in IPv4, too. -- Totus tuus, Glebius. GLEBIUS-RIPN GLEB-RIPE
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20070125183720.GB7922>