svn commit: r206452 - head/sys/netinet
Bruce Simpson
bms at incunabulum.net
Thu Apr 15 17:10:07 UTC 2010
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.
More information about the svn-src-all
mailing list