Design Article

Improvement of libpcap for lossless packet capturing in Linux using PF_RING kernel patch

Joseph Gasparakis and James Chapman

10/5/2009 4:34 PM EDT

Packet capture is a mechanism that copies packets received from the network and pushes them into user space making the frame available to an application for further analysis.

These applications can be network analyzers (also known as network monitors) or an intrusion prevention/detection system. Such common open source applications are tcpdump [1], snort [2], wireshark [3] (previously known as ethereal) , ntop [4] etc.

As the packet propagates from Network Interface Controller (NIC) to the kernel and then to the userspace application, it creates some overhead. Under heavy traffic conditions the percentage of the captured packets over the total number can decrease.

The size of the frame does play a significant factor, as the smaller the packet size the higher the negative impact in the packet capture percentage. The reason for this is that for same throughput the amount of smaller packets is greater then for bigger packet sizes, having as result more need for processing power.

In this article we will describe how one can improve lossless network packet capturing with libpcap by using the PF_RING kernel patch. Libpcap[1] is one of the more vastly open source library for packet capturing and uses by default PF_PACKET protocol in order to transfer the packets from the driver to the userspace.

It is the de facto library that facilitates the packet transition from kernel onto the userspace is libpcap. It provides an API for the programmer to select the capturing interface (device) and gives the ability to compile Linux Packet Filters (LPF) into the kernel for selective packet capturing based on the 5 tuple (protocol, source/destination IP address and source/destination port).

PF_RING is a replacement for PF_PACKET that not only uses memory mapping instead of processing expensive buffer copies from kernel space to userspace, but it also uses ring buffers making to transportation in a more efficient way.

In this article we will also describe an installation guide and a comparison of the libpcap, tested for lossless packet capturing with and without the PF_RING applied.

We will show that for 64 byte packets there was a 17.01% improvement, for 128 byte packets 3.49%, for 256 byte packets 57.82, for 512 byte packets 20.14%, for 1024 byte packets 19.19% and finally for 1518 byte packets, the improvement was 11.15%.

These improvements reveal ability for the existing hardware to allow lossless packet capture at higher data speed rates making more efficient open source IDS and IPS systems that use libpcap. Also any other applications such as protocol analyzers that use libpcap can work more efficiently.

Optimization using PF_RING
PF_RING is a mechanism conceived by Luca Deri [5] for accelerating libpcap. It comprises of a kernel patch and a modified libpcap. This modified libpcap provides exactly the same API to the user but underneath it is using the ring buffers provided by the kernel patch to read packets. The patch copies the packets into the ring straight from the driver. Figure 1 below shows the architecture of PF_RING.

Figure 1 - PF_RING and legacy architecture

Obtaining the PF_RING Source
PF_RING can be obtained using subversion [6]:

    svn co https://svn.ntop.org/svn/ntop/trunk/PF_RING/

The PF_RING package must be moved to /usr/src/kernels/ and the PF_RING environment variable needs to point to that directory. The mkpatch.sh file needs to be edited in order for the kernel version to be specified. Here is an example for the 2.6.24 kernel:

    VERSION=${VERSION:-2}
    PATCHLEVEL=${PATCHLEVEL:-6}
    SUBLEVEL=${SUBLEVEL:-24}

When the above script gets executed it will automatically download the specified kernel source and apply the PF_RING patch. A new directory with the specified and patched kernel will be available.

The specifier "PF_RING" will appear at the end of the kernel version. For the example of the 2.6.24 kernel, the directory /usr/src/kernels/ the directory $PF_RING/workspace/linux-2.6.24PF_RING will be created.


Next:




CapnKernel

10/8/2009 3:03 AM EDT

(Note to readers: Some of the example code above is a bit whacked, for example, '/pfcount "v "I ethX').

Things like PF_RING are necessary because the existing Linux packet capture mechanism is horribly inefficient, requiring two system calls and memory copying for every captured packet. With such a losesome design, it's no wonder packets get dropped.

I recently went through this exercise with a 3G wireless modem. We were experiencing packet loss on capture of about 20%, although the actual TCP performance was fine. I tried PF_RING but had problems:

http://lists.ntop.org/pipermail/ntop/2009-September/014992.html

I also had a problem that with the PF_RING libpcap, I could only capture *USB* packets from the USB 3G modem, not ethernet frames:

http://lists.ntop.org/pipermail/ntop/2009-September/014994.html

Nobody on the ntop (home of PF_RING) mailing list had any answers for me.

I also found that when capturing from a PCI ethernet card, packet loss was much reduced, but was not zero.

In digging around, I found an alternative approach: A kernel option called "CONFIG_PACKET_MMAP", which has been part of the stock Linux kernel for five years:

http://lxr.linux.no/linux/Documentation/networking/packet_mmap.txt

On our OS (Fedora) this option is already turned on, so if you go the CONFIG_PACKET_MMAP route, there will be no kernel patching, and you may not need to recompile and deploy a new kernel. That's a win.

The stock libpcap, however, does not support CONFIG_PACKET_MMAP. You can download a version that does from here:

http://public.lanl.gov/cpw/

Building this libpcap is similar to in the article.

Using CONFIG_PACKET_MMAP, we were able to achieve 0% captured packet loss on our Fedora boxes, with no need to roll out a new kernel. I have also tested it on gigabit ethernet, and I can capture with 0% loss.

I'm not trying to say one option is better than another, but it's good to have a choice, and for me, CONFIG_PACKET_MMAP worked better.

Sign in to Reply



Joseph Gasparakis

10/9/2009 11:38 AM EDT

Hi CapnKernel (and other readers)

Thank you for your comment. You are right, using mmap is an improvement for pushing packets up into userspace as you avoid the expensive buffer copies and then using the libpcap_mmap you can incorporate the benefits into any packet processing application that relies on libpcap.

Since you are happy with the performance (and maybe other readers would be just like you) libpcap_mmap is giving to you that is fine, however we have seen PF_RING giving generally better performance if you can afford to have a patched kernel.

In two words: It all depends on how much performance boost you need and if you want a patched kernel.

Sign in to Reply



Please sign in to post comment

Navigate to related information

Datasheets.com Parts Search

185 million searchable parts
(please enter a part number or hit search to begin)

Feedback Form