[Bug 257511] iflib: enabling promisc under netmap causes lockup when interface is down

From: <bugzilla-noreply_at_freebsd.org>
Date: Fri, 30 Jul 2021 19:35:47 UTC
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=257511

            Bug ID: 257511
           Summary: iflib: enabling promisc under netmap causes lockup
                    when interface is down
           Product: Base System
           Version: 12.2-STABLE
          Hardware: amd64
                OS: Any
            Status: New
          Severity: Affects Only Me
          Priority: ---
         Component: kern
          Assignee: bugs@FreeBSD.org
          Reporter: brian90013@gmail.com

Created attachment 226806
  --> https://bugs.freebsd.org/bugzilla/attachment.cgi?id=226806&action=edit
Test program demonstrating issue

Hello,

I am using the igb driver to collect packets promiscuously. Since I am using
netmap, I placed the ioctl(SIOCSIFFLAGS) call to enable promisc after netmap
configuration. That way I avoid sending a flood of packets up the network stack
if there are packets flowing in on start up. However, I have noticed if I
follow these steps, but have not also marked the interface as up, the driver
will lock up when I try to receive packets. In my testing, killing the process
does not solve the problem - I end up rebooting to restore functionality. I
have observed this with multiple iflib drivers - igb, ixgbe, ixl, and ice -
leading me to strongly believe it is a problem in iflib. Other drivers I have
tested don't allow netmap configuration for an interface that isn't up.

The test program I attached shows my procedure. By running './promisc
netmap:igb0', the program opens the port in netmap, then sets the promisc bit,
then tries to read a packet. If the interface is up, everything works and it
prints 'success'. If the interface is not up, the program will hang. I often
don't assign an address to a port that is being used by netmap for promiscuous
mode so this problem gets me.

Looking at the iflib.c code, function iflib_if_ioctl(), the SIOCSIFFLAGS case
checks if the interface is up, then if running, and finally checks the bits. If
the interface is down as in my example, then it checks for running - which I
believe is true since netmap has been initialized. In that conditional, the
function calls iflib_stop() which has the following comment in it:

    /*
     * Stop any pending txsync/rxsync and prevent new ones
     * form starting. Processes blocked in poll() will get
     * POLLERR.
     */
    netmap_disable_all_rings(ctx->ifc_ifp);

The ioctl() call returns 0 in this case so there's no sign that netmap has been
disabled. However, when the poll() call then tries to rxsync() it hangs.

I can avoid problems by making sure the interface is always up before starting
my program. However, I'd prefer iflib not hang should an interface be down.

-- 
You are receiving this mail because:
You are the assignee for the bug.