Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 15 Apr 2010 18:10:04 +0100
From:      Bruce Simpson <bms@incunabulum.net>
To:        Bruce M Simpson <bms@FreeBSD.org>
Cc:        svn-src-head@freebsd.org, svn-src-all@freebsd.org, src-committers@freebsd.org
Subject:   Re: svn commit: r206452 - head/sys/netinet
Message-ID:  <4BC7486C.9010804@incunabulum.net>
In-Reply-To: <201004101205.o3AC5VGp074266@svn.freebsd.org>
References:  <201004101205.o3AC5VGp074266@svn.freebsd.org>

next in thread | previous in thread | raw e-mail | index | archive | help
On 04/10/10 13:05, Bruce M Simpson wrote:
> Log:
>    Fix a few issues related to the legacy 4.4 BSD multicast APIs.
>
>    IPv4 addresses can and do change during normal operation. Testing by
>    pfSense developers exposed an issue where OpenOSPFD was using the IPv4
>    address to leave the OSPF link-scope multicast groups on a dynamic
>    OpenVPN tun interface, rather than using RFC 3678 with the interface
>    index, which won't be raced when the interface's addresses change.
>    

I should point out that IP multicast is counter-intuitive in many areas. 
It seems that knowledge of how to work with it effectively is not that 
widespread. People who have a need to use it, often have very specific 
requirements.

IP multicast group membership is always scoped to physical links [1]. 
The 4.4BSD API originally used the "primary IP address" to identify each 
link. Unfortunately this is not a persistent identifier, especially so 
in the use-case which had problems.

In the updated API specified in RFC 3678, the primary key for multicast 
memberships, changes to the interface index. routed(8) in FreeBSD's SVN 
tree uses this new API; thanks to phk for reviewing and testing my change.

In the case of OpenOSPFD+OpenVPN, the issue manifested itself in 
situations where this "primary IP address" changed. OpenVPN shims 
address assignment as part of its wire protocol, which is where the 
address change originates.

This is purely a by-product of using an API which depends on using an 
IPv4 address as a key (IP_ADD_MEMBERSHIP/IP_DROP_MEMBERSHIP), when that 
key may change at any time.

There's some time domain uncertainty with that change. PF_ROUTE is an 
out-of-band mechanism used by OpenOSPFD to learn about the address 
change, and it is dispatched separately from the change itself; there 
may be queueing and context switches involved. It also creates some 
ambiguity for in_multi instances, which the kernel may not be able to 
resolve, if that key has been blown away. Fortunately, such ambiguity is 
private to each socket.

Furthermore, this makes IGMP somewhat unreliable, although mechanisms do 
exist in the protocol to work-around the end-station's identifier being 
lost in this way. The upstream IGMP querier (usually the mcast router) 
will hold state based on the end-station's "primary IP address", this 
will eventually time out due to unanswered queries.

MLD side-steps this by always requiring an IPv6 link-scope address in 
control traffic. Using the more recent multicast RFCs, supported now by 
Windows, Linux, OpenSolaris, and now FreeBSD, can side-step these 
issues; it is the preferred API.

P.S. HEAD was probably already resilient against this for joins. I plan 
to MFC a similar version of this change to 8 soon.

[1] sendto() to an IP multicast address, without an interface specified, 
makes no sense -- unless the host is also an mcast forwarder. You can 
get away with default route resolution through the routing tables up to 
a point, but if your box is multihomed, all bets are off.



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?4BC7486C.9010804>