Un pequeño repositorio que usaré para almacenar mi progreso y probar programas desde el DPDK, una biblioteca de derivación del kernel muy útil para el procesamiento rápido de paquetes.
Este repositorio utiliza mi proyecto común DPDK en un esfuerzo por simplificar las cosas.
ADVERTENCIA : sigo agregando más ejemplos a medida que pasa el tiempo y necesito probar nuevas funciones/métodos.
Si desea compilar el DPDK utilizando las opciones predeterminadas, lo siguiente debería funcionar suponiendo que tenga requisitos como ninja
y meson
.
git clone https://github.com/DPDK/dpdk.git
cd dpdk/
meson build
cd build
ninja
sudo ninja install
sudo ldconfig
Todos los archivos de encabezado necesarios del DPDK se almacenarán dentro de /usr/local/include/
.
Puedes recibir ninja
y meson
usando lo siguiente.
sudo apt update
sudo apt install python3 python3-pip
sudo pip3 install meson # Pip3 is used because 'apt' has an outdated version of Meson usually.
sudo apt install ninja-build
Puede usar git
y make
para crear los archivos fuente dentro de este repositorio.
git clone --recursive https://github.com/gamemann/The-DPDK-Examples.git
cd The-DPDK-Examples/
make
Los ejecutables se crearán dentro del directorio build/
de forma predeterminada.
Todas las aplicaciones DPDK en este repositorio admiten los parámetros EAL de DPDK. Estos se pueden encontrar aquí.
Esto es útil para especificar la cantidad de núcleos L y puertos a configurar, por ejemplo.
En esta aplicación DPDK, se descartarán todos los paquetes que lleguen al puerto de destino UDP 8080. De lo contrario, si el tipo de encabezado Ethernet del paquete es IPv4 o VLAN, intercambiará las direcciones MAC e IP de origen/destino junto con los puertos de origen/destino UDP y luego enviará el paquete por la ruta TX (básicamente, reenviando el paquete de donde vino). .
Además de los parámetros EAL, lo siguiente está disponible específicamente para esta aplicación.
-p --portmask => The port mask to configure (e.g. 0xFFFF).
-P --portmap => The port map to configure (in '(x, y),(b,z)' format).
-q --queues => The amount of RX and TX queues to setup per port (default and recommended value is 1).
-x --promisc => Whether to enable promiscuous on all enabled ports.
-s --stats => If specified, will print real-time packet counter stats to stdout.
He aquí un ejemplo:
./dropudp8080 -l 0-1 -n 1 -- -q 1 -p 0xff -s
En esta aplicación DPDK, se crea una tabla hash de enrutamiento simple donde la clave es la dirección IP de destino y el valor es la dirección MAC a la que reenviar.
Las rutas se leen del archivo /etc/l3fwd/routes.txt
en el siguiente formato.
<ip address> <mac address in xx:xx:xx:xx:xx:xx>
El siguiente es un ejemplo.
10.50.0.4 ae:21:14:4b:3a:6d
10.50.0.5 d6:45:f3:b1:a4:3d
Cuando se procesa un paquete, nos aseguramos de que sea un paquete IPv4 o VLAN (en este caso, compensamos los datos del paquete en cuatro bytes para poder procesar el resto del paquete sin problemas). Luego, realizamos una búsqueda siendo la IP de destino la clave en la tabla hash de ruta. Si la búsqueda es exitosa, la dirección MAC de origen se reemplaza con la dirección MAC de destino (los paquetes saldrán por el mismo puerto al que llegan ya que creamos un búfer y una cola de TX) y la dirección MAC de destino se reemplaza con la dirección MAC de la IP. fue asignado desde el archivo de rutas mencionado anteriormente. De lo contrario, el paquete se descarta y se incrementa el contador de paquetes descartados.
Además de los parámetros EAL, lo siguiente está disponible específicamente para esta aplicación.
-p --portmask => The port mask to configure (e.g. 0xFFFF).
-P --portmap => The port map to configure (in '(x, y),(b,z)' format).
-q --queues => The amount of RX and TX queues to setup per port (default and recommended value is 1).
-x --promisc => Whether to enable promiscuous on all enabled ports.
-s --stats => If specified, will print real-time packet counter stats to stdout.
He aquí un ejemplo:
./simple_l3fwd -l 0-1 -n 1 -- -q 1 -p 0xff -s
En esta aplicación, si una IP de origen iguala o excede los paquetes por segundo o bytes por segundo especificados en la línea de comando, los paquetes se descartan. De lo contrario, las direcciones IP y Ethernet se intercambian junto con los puertos TCP/UDP y el paquete se reenvía por la ruta TX.
Las estadísticas de paquetes también se incluyen con el indicador -s
.
Se admiten las siguientes opciones de línea de comando.
-p --portmask => The port mask to configure (e.g. 0xFFFF).
-P --portmap => The port map to configure (in '(x, y),(b,z)' format).
-q --queues => The amount of RX and TX queues to setup per port (default and recommended value is 1).
-x --promisc => Whether to enable promiscuous on all enabled ports.
-s --stats => If specified, will print real-time packet counter stats to stdout.
--pps => The packets per second to limit each source IP to.
--bps => The bytes per second to limit each source IP to.
He aquí un ejemplo:
./ratelimit -l 0-1 -n 1 -- -q 1 -p 0xff -s
NOTA : esta aplicación admite el reciclaje de LRU a través de una función personalizada que creé en el proyecto común DPDK, check_and_del_lru_from_hash_table()
. Asegúrese de definir USE_HASH_TABLES
antes de incluir el archivo de encabezado común DPDK cuando utilice esta función.
Esta es una pequeña aplicación que implementa un método LRU manual para tablas hash. Durante un tiempo he estado intentando que las tablas LRU funcionen desde estas bibliotecas. Sin embargo, no tuve éxito en inicializar la tabla.
Por lo tanto, decidí seguir usando estas bibliotecas e implementar mi propia funcionalidad LRU. Básicamente uso la función rte_hash_get_key_with_position()
para recuperar la clave más antigua para eliminar. Sin embargo, parece que la nueva entrada se inserta en la posición que se eliminó más recientemente, por lo que debe seguir incrementando el valor de la posición hasta el máximo de entradas de la tabla. Dicho esto, una vez que el valor de la posición exceda las entradas máximas de la tabla, deberá volver a establecerlo en 0.
No se necesitan opciones de línea de comando, pero los parámetros EAL aún son compatibles. Sin embargo, no harán la diferencia.
He aquí un ejemplo:
./ratelimit