DPDK (Data Plane Development Kit) es un conjunto de bibliotecas y drivers que permite a una aplicación leer y enviar paquetes directamente desde la tarjeta de red, sin pasar por la pila de red del kernel. En lugar de interrupciones y llamadas al sistema por paquete, un núcleo de CPU sondea la tarjeta en bucle, lo que permite procesar millones de paquetes por segundo por núcleo. En este tutorial instalarás DPDK desde los repositorios de Ubuntu 24.04, prepararás huge pages e IOMMU, vincularás una tarjeta de red al driver vfio-pci, la probarás con dpdk-testpmd y compilarás una aplicación mínima.
Requisitos previos
Para seguir esta guía necesitas:
- Un servidor con Ubuntu 24.04 LTS, preferiblemente un servidor dedicado, y un usuario no root con privilegios
sudo. - Una tarjeta de red dedicada a DPDK, distinta de la que usas para SSH. Cuando vinculas un puerto a DPDK desaparece del sistema operativo: si es el único, perderás la conexión con el servidor.
- Una NIC soportada por DPDK. La lista está en la documentación de drivers de DPDK; Intel (
ixgbe,i40e,ice), Mellanox/NVIDIA (mlx5) y Broadcom (bnxt) son las más habituales. - Al menos 4 núcleos de CPU y 4 GB de RAM libres.
- Acceso a la consola del servidor (IPMI/KVM) por si un cambio de red o de arranque te deja sin SSH.
NotaDPDK también funciona dentro de máquinas virtuales con tarjetas
virtio, pero el rendimiento depende del host y hace falta una segunda interfaz de red libre. Para medir rendimiento real, usa bare metal.
Paso 1: Comprobar el hardware
Lista las tarjetas de red con su dirección PCI y el identificador de fabricante:
lspci -nn | grep -i ethernet
03:00.0 Ethernet controller [0200]: Intel Corporation Ethernet Controller X710 for 10GbE SFP+ [8086:1572] (rev 02)
03:00.1 Ethernet controller [0200]: Intel Corporation Ethernet Controller X710 for 10GbE SFP+ [8086:1572] (rev 02)
Identifica qué interfaz del sistema corresponde a cada dirección PCI y cuál tiene la IP por la que te conectas:
ls -l /sys/class/net/ | grep pci
ip -br addr
En el resto de la guía se usa el puerto 0000:03:00.1 (interfaz enp3s0f1), que no tiene IP ni se usa para SSH. Sustitúyelo por el tuyo.
Paso 2: Instalar DPDK
Ubuntu 24.04 incluye DPDK 23.11 LTS en sus repositorios. Instala las herramientas, las bibliotecas de desarrollo y lo necesario para compilar:
sudo apt update
sudo apt install dpdk libdpdk-dev build-essential pkg-config
Comprueba la versión instalada:
pkg-config --modversion libdpdk
23.11.1
El paquete dpdk instala en /usr/bin las utilidades que usarás a continuación: dpdk-devbind.py, dpdk-hugepages.py y dpdk-testpmd.
Paso 3: Reservar huge pages
DPDK coloca los buffers de paquetes en huge pages para evitar fallos de TLB y garantizar memoria física contigua. Reserva 2 GB en páginas de 2 MB con la utilidad de DPDK:
sudo dpdk-hugepages.py --setup 2G
Comprueba la reserva:
dpdk-hugepages.py --show
Node Pages Size Total
0 1024 2Mb 2Gb
Hugepages mounted on /dev/hugepages
Ubuntu ya monta hugetlbfs en /dev/hugepages al arrancar, pero la reserva de páginas se pierde con cada reinicio. Para hacerla permanente, crea un archivo de sysctl:
sudo nano /etc/sysctl.d/60-dpdk-hugepages.conf
Añade esta línea:
vm.nr_hugepages = 1024
En servidores con varios sockets, cada nodo NUMA necesita páginas propias para la NIC que tiene conectada. dpdk-hugepages.py --show muestra el reparto por nodo.
Paso 4: Activar la IOMMU
El driver vfio-pci usa la IOMMU para que la tarjeta solo pueda escribir en la memoria asignada a la aplicación DPDK. Es el driver recomendado porque no necesita desactivar protecciones del kernel.
Comprueba si la IOMMU ya está activa:
ls /sys/kernel/iommu_groups/ | wc -l
Si el resultado es 0, activa la IOMMU en los parámetros de arranque. Asegúrate también de que VT-d (Intel) o AMD-Vi/IOMMU (AMD) están habilitados en la BIOS.
sudo nano /etc/default/grub
En un procesador Intel, añade estos parámetros a GRUB_CMDLINE_LINUX_DEFAULT, conservando los que ya hubiera:
GRUB_CMDLINE_LINUX_DEFAULT="intel_iommu=on iommu=pt"
En AMD la IOMMU se activa por defecto si está habilitada en la BIOS, así que basta con iommu=pt. Este parámetro (passthrough) evita traducir las direcciones de los dispositivos que sigue gestionando el kernel, para que no pierdan rendimiento.
Aplica el cambio y reinicia:
sudo update-grub
sudo reboot
Tras el reinicio, el número de grupos IOMMU debe ser mayor que cero:
ls /sys/kernel/iommu_groups/ | wc -l
58
Paso 5: Cargar el módulo vfio-pci
Carga el módulo y configúralo para que se cargue en cada arranque:
sudo modprobe vfio-pci
echo vfio-pci | sudo tee /etc/modules-load.d/vfio-pci.conf
Verifica que está cargado:
lsmod | grep vfio_pci
vfio_pci 16384 0
vfio_pci_core 94208 1 vfio_pci
Paso 6: Vincular la tarjeta de red a vfio-pci
Consulta el estado de las tarjetas de red desde el punto de vista de DPDK:
dpdk-devbind.py --status-dev net
Network devices using kernel driver
===================================
0000:03:00.0 'Ethernet Controller X710 for 10GbE SFP+ 1572' if=enp3s0f0 drv=i40e unused=vfio-pci *Active*
0000:03:00.1 'Ethernet Controller X710 for 10GbE SFP+ 1572' if=enp3s0f1 drv=i40e unused=vfio-pci
*Active* marca las interfaces con rutas o IP configuradas; nunca vincules esas. Apaga la interfaz que vas a usar y vincúlala a vfio-pci:
sudo ip link set enp3s0f1 down
sudo dpdk-devbind.py --bind=vfio-pci 0000:03:00.1
Vuelve a consultar el estado:
dpdk-devbind.py --status-dev net
Network devices using DPDK-compatible driver
============================================
0000:03:00.1 'Ethernet Controller X710 for 10GbE SFP+ 1572' drv=vfio-pci unused=i40e
Network devices using kernel driver
===================================
0000:03:00.0 'Ethernet Controller X710 for 10GbE SFP+ 1572' if=enp3s0f0 drv=i40e unused=vfio-pci *Active*
La interfaz enp3s0f1 ya no aparece en ip link: ahora la controla DPDK.
ImportanteLas tarjetas Mellanox/NVIDIA ConnectX (
mlx5) no se vinculan avfio-pci. Usan un driver bifurcado que convive con el driver del kernel, así que con ellas debes saltarte este paso y dejar la interfaz con su drivermlx5_core.
La vinculación se pierde al reiniciar. Para hacerla permanente, instala driverctl, que guarda un override del driver para esa dirección PCI:
sudo apt install driverctl
sudo driverctl set-override 0000:03:00.1 vfio-pci
Comprueba que el override está registrado:
driverctl list-overrides
0000:03:00.1 vfio-pci
Paso 7: Probar el puerto con dpdk-testpmd
dpdk-testpmd es la aplicación de pruebas de DPDK: inicializa los puertos, reenvía o recibe tráfico y muestra estadísticas. Lánzala en modo interactivo usando los núcleos 2 y 3 y solo el puerto vinculado:
sudo dpdk-testpmd -l 2-3 -a 0000:03:00.1 -- -i --port-topology=loop
Los argumentos antes de -- son del entorno de DPDK (EAL): -l 2-3 indica los núcleos (el primero se usa como núcleo principal y el resto para reenviar paquetes) y -a limita DPDK al puerto indicado. Los que van después son de testpmd: -i abre el modo interactivo y --port-topology=loop hace que un único puerto reenvíe lo que recibe por él mismo.
Si todo está bien, verás la inicialización y el prompt de testpmd:
EAL: Detected CPU lcores: 16
EAL: Detected NUMA nodes: 1
EAL: Selected IOVA mode 'VA'
EAL: VFIO support initialized
EAL: Using IOMMU type 1 (Type 1)
Configuring Port 0 (socket 0)
Port 0: 3C:FD:FE:XX:XX:XX
Checking link statuses...
Done
testpmd>
Consulta la información del puerto, incluido el estado del enlace:
testpmd> show port info 0
Pon el puerto en modo de solo recepción, arranca y revisa las estadísticas mientras llega tráfico al puerto (desde otra máquina o un generador de tráfico):
testpmd> set fwd rxonly
testpmd> start
testpmd> show port stats 0
######################## NIC statistics for port 0 ########################
RX-packets: 18342751 RX-missed: 0 RX-bytes: 1100565060
RX-errors: 0
RX-nombuf: 0
TX-packets: 0 TX-errors: 0 TX-bytes: 0
Throughput (since last show)
Rx-pps: 14880952 Rx-bps: 7142857000
Tx-pps: 0 Tx-bps: 0
############################################################################
RX-missed cuenta los paquetes que la tarjeta descartó porque la aplicación no los recogió a tiempo; si crece, necesitas más núcleos o colas. Para reenviar el tráfico de vuelta usa set fwd io o set fwd macswap. Detén la prueba y sal:
testpmd> stop
testpmd> quit
Paso 8: Compilar una aplicación DPDK mínima
Las aplicaciones DPDK se compilan contra libdpdk usando pkg-config, que aporta las opciones de compilación y enlazado correctas. Crea un directorio de trabajo y un programa que inicialice el entorno y cuente los puertos disponibles:
mkdir -p ~/dpdk-hola
nano ~/dpdk-hola/main.c
#include <stdio.h>
#include <stdlib.h>
#include <rte_eal.h>
#include <rte_debug.h>
#include <rte_ethdev.h>
int main(int argc, char **argv)
{
int ret = rte_eal_init(argc, argv);
if (ret < 0)
rte_exit(EXIT_FAILURE, "No se pudo inicializar el EAL\n");
printf("Puertos DPDK disponibles: %u\n", rte_eth_dev_count_avail());
rte_eal_cleanup();
return 0;
}
Compílalo:
cd ~/dpdk-hola
gcc -O2 main.c -o hola $(pkg-config --cflags --libs libdpdk)
Ejecútalo con los mismos argumentos de EAL que usaste con testpmd:
sudo ./hola -l 2 -a 0000:03:00.1
EAL: Detected CPU lcores: 16
EAL: Detected NUMA nodes: 1
EAL: VFIO support initialized
Puertos DPDK disponibles: 1
Para un bucle completo de recepción y envío, el punto de partida recomendado es el ejemplo skeleton (basicfwd.c) del código fuente de DPDK, disponible en examples/skeleton del repositorio oficial. Usa la rama o etiqueta de la misma versión que muestra pkg-config --modversion libdpdk y compílalo con make desde su directorio.
Paso 9: Devolver la tarjeta al kernel
Cuando termines las pruebas, puedes devolver la tarjeta a su driver original (el que aparecía como unused= en el paso 6). Si usaste driverctl, elimina primero el override:
sudo driverctl unset-override 0000:03:00.1
Si no lo usaste, vincúlala a mano:
sudo dpdk-devbind.py --bind=i40e 0000:03:00.1
Comprueba que la interfaz vuelve a aparecer en el sistema:
ip -br link show enp3s0f1
Solución de problemas
EAL: No free 2048 kB hugepages reported. No hay huge pages reservadas o están todas en uso por otro proceso DPDK. Repite el paso 3 y comprueba condpdk-hugepages.py --show.vfio-pci: probe of 0000:03:00.1 failed with error -22oEAL: VFIO group is not viable. La IOMMU no está activa o la tarjeta comparte grupo IOMMU con otro dispositivo que sigue en uso por el kernel. Revisa el paso 4 y el grupo conls /sys/bus/pci/devices/0000:03:00.1/iommu_group/devices/.testpmdno encuentra ningún puerto. La dirección PCI de-ano coincide con la vinculada, o la tarjeta no está soportada por los drivers de DPDK de tu versión. Compruebadpdk-devbind.py --status-dev net.RX-missedcrece. La aplicación no da abasto: añade núcleos con-l, usa varias colas (--rxqy--txqentestpmd) y fija los núcleos de DPDK en el mismo nodo NUMA que la tarjeta.- Has perdido el acceso SSH. Vinculaste la interfaz de gestión. Entra por la consola del servidor y devuélvela al kernel como en el paso 9.
Conclusión
Tienes DPDK 23.11 instalado en Ubuntu 24.04, con huge pages, IOMMU y una tarjeta vinculada a vfio-pci de forma permanente, has comprobado el puerto con dpdk-testpmd y has compilado una aplicación contra libdpdk. Como siguientes pasos, aísla los núcleos que usa DPDK del planificador del kernel para evitar interrupciones, estudia el ejemplo l2fwd del código fuente para un reenvío entre puertos completo y mide el rendimiento con un generador de tráfico como TRex o pktgen-dpdk.
