cvs commit: src/sys/compat/ndis ndis_var.h subr_ndis.c
src/sys/dev/if_ndis if_ndis.c if_ndisvar.h
Sam Leffler
sam at errno.com
Wed Jul 7 12:19:23 PDT 2004
On Wednesday 07 July 2004 10:46 am, Bill Paul wrote:
> - Create am NDIS_INITIALIZED() macro in if_ndisvar.h and use it in
> if_ndis.c to test whether the device has been initialized rather
> than checking for the presence of the IFF_UP flag in if_flags.
> While debugging the previous problem, I noticed that bringing
> up the device would always produce failures from ndis_setmulti().
> It turns out that the following steps now occur during device
> initialization:
>
> - IFF_UP flag is set in if_flags
> - ifp->if_ioctl() called with SIOCSIFADDR (which we don't handle)
> - ifp->if_ioctl() called with SIOCADDMULTI
> - ifp->if_ioctl() called with SIOCADDMULTI (again)
> - ifp->if_ioctl() called with SIOCADDMULTI (yet again)
> - ifp->if_ioctl() called with SIOCSIFFLAGS
>
> Setting the receive filter and multicast filters can only be done
> when the underlying NDIS driver has been initialized, which is done
> by ifp->if_init(). However, we don't call ifp->if_init() until
> ifp->if_ioctl() is called with SIOCSIFFLAGS and IFF_UP has been
> set. It appears that now, the network stack tries to add multicast
> addresses to interface's filter before those steps occur. Normally,
> ndis_setmulti() would trap this condition by checking for the IFF_UP
> flag, but the network code has in fact set this flag already, so
> ndis_setmulti() is fooled into thinking the interface has been
> initialized when it really hasn't.
>
> It turns out this is usually harmless because the ifp->if_init()
> routine (in this case ndis_init()) will set up the multicast
> filter when it initializes the hardware anyway, and the underlying
> routines (ndis_get_info()/ndis_set_info()) know that the driver/NIC
> haven't been initialized yet, but you end up spurious error messages
> on the console all the time.
>
> Something tells me this new behavior isn't really correct. I think
> the intention was to fix it so that ifp->if_init() is only called
> once when we ifconfig an interface up, but the end result seems a
> little bogus: the change of the IFF_UP flag should be propagated
> down to the driver before calling any other ioctl() that might actually
> require the hardware to be up and running.
This "new behaviour" is many many months old (assuming it's what I think it
is). The if_init routine is only called by the 802.11 ioctl routine when you
mark the interface up to avoid forcing a device initialization (and run of
the 802.11 state machine) on every ioctl that's done before marking the if
up. This is done based on the setting of the IFF_UP flag. In general IFF_UP
means the interface is "ready for traffic to flow". A device should be
capable of editing it's multicast state as soon as it marks itself
IFF_RUNNING.
Sam
More information about the cvs-all
mailing list