[Top] [All Lists]

Re: Promiscuous and Multicast semantics

To: Brad Hards <bhards@xxxxxxxxxxxxxx>
Subject: Re: Promiscuous and Multicast semantics
From: Donald Becker <becker@xxxxxxxxx>
Date: Sat, 8 Sep 2001 11:32:01 -0400 (EDT)
Cc: netdev@xxxxxxxxxxx
In-reply-to: <>
Sender: owner-netdev@xxxxxxxxxxx
On Sat, 8 Sep 2001, Brad Hards wrote:

> The question I have relates to how multicast and promiscuous stuff gets
> enabled.
> Promiscuous mode first:
> I take it that, to enable promiscuous mode, ifconfig (or equivalant) sets the
> net_device.flags with IFF_PROMISC, and then calls
> net_device.set_multicast_list. To disable, we clear IFF_PROMISC and then call
> net_device.set_multicast_list.

Correct.  Every change to the Rx filter is communicated by a call to

[[ This name is slightly misleading: at one point this call had three
parameters, including the list to set.  Someone made the bogus change of
dropping two parameters without changing the function name.  Doing this
made backwards-compatible code very ugly. ]]

> Multicast mode:
> If we want all the multicast addresses, ifconfig sets net->flags with
> IFF_ALLMULTI and then calls net_device.set_multicast_list. Same to disable
> receiving every multicast address.
> If we just want some of the multicast addresses, we set IFF_MULTICAST, and get
> the number of addresses as net_device.mc_count and the addresses as a linked
> list as net_device.mc_list, and then a call to net_device.set_multicast_list.


> What is the interaction between promiscuous mode and multicast mode? If I set
> promiscuous mode, is there any required changes to multicast mode (enabled or
> disabled)?

You should refer to the code in pci-skeleton.c or the older
(ISA-oriented) skeleton.c to confirm your understanding.

IFF_PROMISC overrides all else.  It implies ALLMULTI.
  Most hardware has separate bits to enable HW_ALLPHYS and HW_ALLMULTI.  The
  netdriver interface does not match this: set both HW_ALLPHYS and HW_ALLMULTI
  when IFF_PROMISC is set.

> What is the interaction between IFF_ALLMULTI and IFF_MULTICAST? If I set
> specific addresses, should ALL_MULTI be disabled? If I set ALL_MULTI, should
> the list of addresses be cleared?

IFF_ALLMULTI overrides the multicast list.
 You need not check the multicast list when IFF_ALLMULTI is set.

Most of my drivers use the module parameter 'multicast_filter_limit' to
treat too many multicast addresses as the equivalent of ALLMULTI.  The
default value is set based on the multicast filter size and how painful
it is to set the multicast list.

For instance, on Intel chips it is very time consuming to change a long
multicast list, and the receiver is shut off (!) while the chip is
loading the new list.

Other chips have register-loaded multicast hash filters based on the CRC
of the address.  The cost of loading the filter to the chip is constant,
independent of the multicast filter list length.  There the controlling
factor is when the hash filter becomes ineffective and the (trivial)
effort of computing the CRC is wasted.

Keep in mind that a single write the Ethernet chip (even on PCI) might
cost the same as executing thousands of cached instructions.  Doing an
unconditional write might look simpler, but keeping the old state around
to avoid a duplicate write is now well worth the complexity.

> If I have previously set a multicast list, and the user changes it with
> ifconfig, will I get the whole list again, or just the changes? If just
> changes, how do I know that I have to delete some?

The whole list.  You have to recalculate your filter.  While it might
seem wasteful, this is the most efficient method with the common case of
a short multicast list.  If you have a long multicast list (very rare)
you should effectively do ALLMULTI as above.

> If multicast is disabled (IFF_MULTICAST == 0), should I clear the multicast
> list?


Donald Becker                           becker@xxxxxxxxx
Scyld Computing Corporation   
410 Severn Ave. Suite 210               Second Generation Beowulf Clusters
Annapolis MD 21403                      410-990-9993

<Prev in Thread] Current Thread [Next in Thread>