tcpdump mailing list archives

Re: libpcap capture performance drop


From: Guy Harris <guy () alum mit edu>
Date: Fri, 27 May 2011 10:39:20 -0700


On May 27, 2011, at 10:16 AM, Rick Jones wrote:

Is this new libpcap going to be guaranteed that the underlying NIC HW
isn't doing Large Receive Offload, or that the tracepoint in the stack
is below any stack's attempt to do Generic Receive Offload?

If

        1) your kernel supports the ethtool ioctls and libpcap was built with headers that support those ioctls

and

        2) the code below (which I checked in a few days ago) can detect all the forms of offloading that could cause 
large "packets" to be delivered

then, yes, the new libpcap will not trust the MTU value if any of the forms of offloading are enabled.  (It also checks 
for TCP segmentation offloading and UDP fragmentation offloading, so that large *transmitted* "packets" won't cause a 
problem.)

/*
 * Find out if we have any form of fragmentation/reassembly offloading.
 */
#ifdef SIOCETHTOOL
static int
iface_ethtool_ioctl(pcap_t *handle, int cmd, const char *cmdname)
{
        struct ifreq    ifr;
        struct ethtool_value eval;

        memset(&ifr, 0, sizeof(ifr));
        strncpy(ifr.ifr_name, handle->opt.source, sizeof(ifr.ifr_name));
        eval.cmd = cmd;
        ifr.ifr_data = (caddr_t)&eval;
        if (ioctl(handle->fd, SIOCETHTOOL, &ifr) == -1) {
                if (errno == EOPNOTSUPP) {
                        /*
                         * OK, let's just return 0, which, in our
                         * case, either means "no, what we're asking
                         * about is not enabled" or "all the flags
                         * are clear (i.e., nothing is enabled)".
                         */
                        return 0;
                }
                snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
                    "%s: SIOETHTOOL(%s) ioctl failed: %s", handle->opt.source,
                    cmdname, strerror(errno));
                return -1;
        }
        return eval.data;       
}

static int
iface_get_offload(pcap_t *handle)
{
        int ret;

        ret = iface_ethtool_ioctl(handle, ETHTOOL_GTSO, "ETHTOOL_GTSO");
        if (ret == -1)
                return -1;
        if (ret)
                return 1;       /* TCP segmentation offloading on */

        ret = iface_ethtool_ioctl(handle, ETHTOOL_GUFO, "ETHTOOL_GUFO");
        if (ret == -1)
                return -1;
        if (ret)
                return 1;       /* UDP fragmentation offloading on */

        /*
         * XXX - will this cause large unsegmented packets to be
         * handed to PF_PACKET sockets on transmission?  If not,
         * this need not be checked.
         */
        ret = iface_ethtool_ioctl(handle, ETHTOOL_GGSO, "ETHTOOL_GGSO");
        if (ret == -1)
                return -1;
        if (ret)
                return 1;       /* generic segmentation offloading on */

        ret = iface_ethtool_ioctl(handle, ETHTOOL_GFLAGS, "ETHTOOL_GFLAGS");
        if (ret == -1)
                return -1;
        if (ret & ETH_FLAG_LRO)
                return 1;       /* large receive offloading on */

        /*
         * XXX - will this cause large reassembled packets to be
         * handed to PF_PACKET sockets on receipt?  If not,
         * this need not be checked.
         */
        ret = iface_ethtool_ioctl(handle, ETHTOOL_GGRO, "ETHTOOL_GGRO");
        if (ret == -1)
                return -1;
        if (ret)
                return 1;       /* generic (large) receive offloading on */

        return 0;
}

-
This is the tcpdump-workers list.
Visit https://cod.sandelman.ca/ to unsubscribe.


Current thread: