Unexpected multicast IPv4 socket behavior
Bruce M. Simpson
bms at FreeBSD.org
Sat Jan 12 12:10:59 PST 2008
Fredrik Lindberg wrote:
> I would expect this _without_ IP_MULTICAST_IF set, however as I said
> the interface had been explicitly set with IP_MULTICAST_IF in all 4
> cases, so there indeed is enough information in the stack to send
> the packet.
Correct. You found a bug. Well done.
> If IP_MULTICAST_IF should be considered legacy, I'll move away from it.
> But, as you said, there is probably a lack of knowledge on how the
> APIs should be used and I have never seen anyone or any document
> (maybe I haven't looked hard enough) that suggests that this usage is
The fact that IPv4 multicast sends appear to work using the default
route is a historical quirk. It is not multicast forwarding.
For a host/endstation, the mere fact that the group was joined on a
given socket, on a given interface, should be enough IP layer
reachability information for the inpcb layer to figure out where to send
the packets. From that point on, it's the problem of the multicast
routers on the path between the end-station and the other members of the
channel, which are normally speaking PIM-SM.
If one follows how IGMP works, then the problem with multicast joins
which are not scoped to an interface is readily obvious. IGMP/MLD is
necessary to inform upstream routers that the channel is being opened --
otherwise, you will not receive traffic for the group, as the state
about the end-station's participation in the channel is never
communicated to routers.
The endpoint address used by the local end of the path in MLD is the
link-scope IPv6 address. In IGMP, it's the first IPv4 address configured
on the interface. Both IGMP and MLD are always scoped to the local link
-- they deal with multicast forwarding and membership state ONLY in the
domain of the link they are used on.
IPv4 has historically not had link-scope addresses, which are one
possible answer to the problem. Ergo there is a problem if the interface
is unnumbered -- or if the inpcb laddr is 0.0.0.0 -- which you have
seen. It should be possible to use IP_MULTICAST_IF as a workaround for
this, however, you found that path is buggy...
I guess the textbooks out there haven't caught up with reality.
> I wouldn't expect anything in 220.127.116.11/4 to fail
> _with_ IP_MULTICAST_IF set.
Correct. This makes the bug even more damaging. It is reasonable for a
system to be using multicast during early boot when all interfaces are
In fact the IGMPv3 RFC suggests no IGMP traffic should be sent for
groups in 18.104.22.168/24, becuase upstream IGMP routers should never be
forwarding these groups between links.
Unfortunately, in practice, this can break layer 2 multicasts for these
groups which traverse IGMP snooping switches.
> IP_SENDIF/SO_BINDTODEVICE seems to show up from time to time, is
> the only reason that it hasn't been implemented simply that nobody
> has done it?
Yup. Everyone seems to be too worried about unicast traffic and bulk I/O
performance to bother much with other applications of IP, so, this sort
of issue gets more airtime elsewhere.
More information about the freebsd-net