rev. 1.94 of netinet/in.c broke CARP

Gleb Smirnoff glebius at FreeBSD.org
Thu Jan 25 18:37:23 UTC 2007


  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


More information about the freebsd-net mailing list