Yes, it does seem broken, kind of surprising we haven't  seen this very 
often. But instead of introducing a new ipif_need_up field, can't you 
deduce it from the already available information ? At the start of 
ip_sioctl_flags_tail(), we have the current state flags in 
ipif->ipif_flags, and the final expected state flags in the 'flags' 
parameter from the lifreq/ifreq struct. If IPIF_UP is set in the latter 
but clear in the former, wouldn't that be 'need_up' ?

Thirumalai

Peter Memishian wrote:
> Some of you may recall that we've sporadically been seeing IPMP group
> destroy bugs wherein a an IPMP group cannot be recreated because the ARP
> plumbing for the group interface didn't get properly destroyed.  Well, I
> finally managed to get a semi-reproducible testcase for the bug yesterday
> and eliminate it.
>
> However, the semi-reproducible testcase itself spurred new questions.  In
> particular, one requirement for destroying a group is that all its data
> addresses must be brought down -- that is, ill_ipif_up_count on group's
> IPMP ill must be zero.  To satisfy this constraint, ifconfig internally
> builds a list of IFF_UP addresses and brings each one down.  However,
> sometimes, despite ifconfig's request to bring each one down, some would
> still be up.  Digging around revealed what seems to be a serious and
> longstanding bug that basically causes bringing down an address to
> silently not work.
>
> To wit, if ipif_down() finds that the address is not quiesced, it enqueues
> the ioctl request returns and EINPROGRESS to ip_sioctl_flags().  Once the
> ipif has quiesced ipif_ill_refrele_tail() calls ip_sioctl_flags_restart(),
> which does:
>
>         ipif_down_tail(ipif);
>         if (ipip->ipi_cmd_type == IF_CMD) {
>                 err = ip_sioctl_flags_tail(ipif,
>                     (uint64_t)(ifr->ifr_flags & 0x0000ffff),
>                     q, mp, B_TRUE);
>         } else {
>                 err = ip_sioctl_flags_tail(ipif, lifr->lifr_flags,
>                     q, mp, B_TRUE);
>         }
>
> Note in particular the last argument to ip_sioctl_flags_tail() -- this
> causes it to *always* bring the ipif back up, contradicting the
> application's request to bring the ipif down.  In contrast, the normal
> (non-asynchronous path) is in ip_sioctl_flags() is careful to do:
>
>               ipif_down_tail(ipif);
>         }
>         return (ip_sioctl_flags_tail(ipif, flags, q, mp, need_up));
>                                                          ^^^^^^^
>
> This seems like a pretty serious bug.  Am I missing something here?
>
> One possible fix would be to remove the need_up argument and instead track
> this state on the ipif via a new ipif_need_up field.
>
>   


Reply via email to