From: Sid ali cherrati <scherrati1@gmail.com>
To: Dmitry Kozlyuk <dmitry.kozliuk@gmail.com>
Cc: users@dpdk.org
Subject: Re: DPDK Flow Filtering Not Working as Expected
Date: Mon, 3 Feb 2025 14:51:46 +0100 [thread overview]
Message-ID: <CALn3+CN_nk0GsFyMoC_VVSkTZ2XaS4=T93-h86tR+RT3sDnn7w@mail.gmail.com> (raw)
In-Reply-To: <20250128214616.3f9324de@sovereign>
[-- Attachment #1: Type: text/plain, Size: 7463 bytes --]
Hello Dmitry,
I followed your suggestions, and this is what I came up with:
#include "../include/flow.h"
#include <stdio.h>
#include <string.h>
int flow_filtering(uint16_t port_id, uint32_t ip_addr, uint16_t udp_port) {
struct rte_flow_error error;
struct rte_flow_attr attr = { .ingress = 1, .priority = 0 };
struct rte_flow_item pattern[4];
struct rte_flow_action action[2];
struct rte_flow *flow;
// Définir le motif Ethernet
memset(pattern, 0, sizeof(pattern));
pattern[0].type = RTE_FLOW_ITEM_TYPE_ETH;
// Définir le motif IPv4
struct rte_flow_item_ipv4 ipv4_spec = { .hdr.dst_addr = RTE_BE32(ip_addr) };
struct rte_flow_item_ipv4 ipv4_mask = { .hdr.dst_addr = RTE_BE32(0xFFFFFFFF)
};
pattern[1].type = RTE_FLOW_ITEM_TYPE_IPV4;
pattern[1].spec = &ipv4_spec;
pattern[1].mask = &ipv4_mask;
// Définir le motif UDP
struct rte_flow_item_udp udp_spec = { .hdr.dst_port = RTE_BE16(udp_port) };
struct rte_flow_item_udp udp_mask = { .hdr.dst_port = RTE_BE16(0xFFFF) };
pattern[2].type = RTE_FLOW_ITEM_TYPE_UDP;
pattern[2].spec = &udp_spec;
pattern[2].mask = &udp_mask;
// Terminer le motif
pattern[3].type = RTE_FLOW_ITEM_TYPE_END;
// Définir l'action
action[0].type = RTE_FLOW_ACTION_TYPE_QUEUE;
struct rte_flow_action_queue queue_action = { .index = 0 };
action[0].conf = &queue_action;
action[1].type = RTE_FLOW_ACTION_TYPE_END;
// Créer la règle de flux
flow = rte_flow_create(port_id, &attr, pattern, action, &error);
if (!flow) {
printf("Erreur lors de la création de la règle de flux : %s\n", error.
message);
return -1;
}
// rte_flow_isolate(port_id, 1, &error);
printf("Règle de flux créée avec succès pour IP %u.%u.%u.%u et port UDP %u\n
",
(ip_addr >> 24) & 0xFF, (ip_addr >> 16) & 0xFF,
(ip_addr >> 8) & 0xFF, ip_addr & 0xFF, udp_port);
return 0;
}
int create_drop_all_rule(uint16_t port_id) {
struct rte_flow_attr attr = { .ingress = 1, .priority = 1};
struct rte_flow_item pattern[2];
struct rte_flow_action actions[2];
struct rte_flow *flow;
struct rte_flow_error error;
pattern[0].type = RTE_FLOW_ITEM_TYPE_ETH;
pattern[1].type = RTE_FLOW_ITEM_TYPE_END;
actions[0].type = RTE_FLOW_ACTION_TYPE_DROP;
actions[1].type = RTE_FLOW_ACTION_TYPE_END;
if (!rte_flow_validate(port_id, &attr, pattern, actions, &error)){
flow = rte_flow_create(port_id, &attr, pattern, actions, &error);
}
if(flow != 0){
printf("Filed to create drop flow filter \n");
return -1;
}
printf("Default drop rule created successfully.\n");
return 0;
}
#include "../include/port.h"
#include "../include/flow.h"
#include <rte_eal.h>
#include <rte_mbuf.h>
#include <rte_ethdev.h>
#include <rte_ether.h>
#include <rte_ip.h>
#include <arpa/inet.h>
#define MAX_PKT_BURST 32
int main(int argc, char **argv) {
struct rte_mempool *mbuf_pool;
int ret;
// Initialiser l'EAL
ret = rte_eal_init(argc, argv);
if (ret < 0) {
rte_exit(EXIT_FAILURE, "Erreur lors de l'initialisation de l'EAL\n");
}
// Créer le pool de mbufs
mbuf_pool = rte_pktmbuf_pool_create("MBUF_POOL", NUM_MBUFS, MBUF_CACHE_SIZE,
0,
RTE_MBUF_DEFAULT_BUF_SIZE, rte_socket_id());
if (!mbuf_pool) {
rte_exit(EXIT_FAILURE, "Impossible de créer le pool de mbufs\n");
}
if (port_init(PORT_ID, mbuf_pool) != 0) {
rte_exit(EXIT_FAILURE, "Erreur initialisation port\n");
}
// Créer la règle principale
uint32_t ip_addr = RTE_IPV4(10, 81, 16, 111);
uint16_t udp_port = 1234;
if (flow_filtering(PORT_ID, ip_addr, udp_port) != 0) {
rte_exit(EXIT_FAILURE, "Erreur création règle principale\n");
}
// Créer la règle drop-all
if (create_drop_all_rule(PORT_ID) != 0) {
rte_exit(EXIT_FAILURE, "Erreur création règle drop-all\n");
}
printf("Traitement des paquets...\n");
struct rte_mbuf *bufs[MAX_PKT_BURST];
while (1) {
// Récupérer un burst de paquets sur la file RX de la queue 0
const uint16_t nb_rx = rte_eth_rx_burst(PORT_ID, 0, bufs, MAX_PKT_BURST);
if (nb_rx > 0) {
printf("Reçu %u paquet(s)\n", nb_rx);
for (uint16_t i = 0; i < nb_rx; i++) {
// Afficher la taille du paquet
printf("Paquet %u : taille = %u octets\n",
i, rte_pktmbuf_pkt_len(bufs[i]));
// Traiter le paquet pour afficher les adresses source et destination
struct rte_ether_hdr *eth_hdr;
eth_hdr = rte_pktmbuf_mtod(bufs[i], struct rte_ether_hdr *);
// Vérifier que le paquet est de type IPv4
if (rte_be_to_cpu_16(eth_hdr->ether_type) == RTE_ETHER_TYPE_IPV4) {
struct rte_ipv4_hdr *ip_hdr;
ip_hdr = (struct rte_ipv4_hdr *)(eth_hdr + 1);
// Récupérer les adresses source et destination (conversion en format hôte)
uint32_t src_ip = rte_be_to_cpu_32(ip_hdr->src_addr);
uint32_t dst_ip = rte_be_to_cpu_32(ip_hdr->dst_addr);
// Convertir les adresses en chaîne de caractères lisible
char src_str[INET_ADDRSTRLEN];
char dst_str[INET_ADDRSTRLEN];
inet_ntop(AF_INET, &src_ip, src_str, INET_ADDRSTRLEN);
inet_ntop(AF_INET, &dst_ip, dst_str, INET_ADDRSTRLEN);
printf("Adresse source : %s\n", src_str);
printf("Adresse destination : %s\n", dst_str);
} else {
printf("Paquet non IPv4, impossible d'extraire les adresses\n");
}
// Libérer le mbuf une fois le traitement terminé
rte_pktmbuf_free(bufs[i]);
}
}
// Petite pause pour éviter une utilisation CPU trop intensive
rte_delay_us_block(100);
}
// Nettoyage
port_cleanup(PORT_ID);
return 0;
}
The issue is that when I implement this, I get an error on the drop filter:
"Failed to create rule." Do you have any idea why this might be happening?
Thank you for your time.
Best regards,
Ali
Le mar. 28 janv. 2025 à 19:46, Dmitry Kozlyuk <dmitry.kozliuk@gmail.com> a
écrit :
> Hi Ali,
>
> 2025-01-28 17:54 (UTC+0100), Sid ali cherrati:
> > I am attempting to use DPDK's rte_flow API to filter incoming packets at
> > the hardware level. My goal is to drop all packets except those with a
> > specific IP address and UDP port.
> >
> > I have implemented the following flow filtering rule in my code:
> > [...]
> > However, despite this configuration, I continue to receive packets with
> > other IP addresses and ports that do not match the specified filter.
>
> Packets that do not match the rule pattern are processed as usual.
> If without the rule queue RX_ID could receive any packet,
> it will also receive them after the rule is created.
> You need another rule with lower priority (BTW, 0 is the highest one)
> that matches all packets and drops them or steers to other queues.
> If you want your DPDK app to only process packets matching the rule
> and to leave all other traffic for the OS to process,
> flow isolated mode may be what you're looking for:
>
>
> https://doc.dpdk.org/guides/prog_guide/ethdev/flow_offload.html#flow-isolated-mode
>
> > Could you provide any insights into why the filtering isn't working as
> > expected? Any advice on ensuring the rule is properly applied at the
> > hardware level would be greatly appreciated.
>
> The usual way to check that the rule is matched
> is to all a counter to the rule and check if it increases.
> I suggest using testpmd for playing with flow rules:
>
>
> https://doc.dpdk.org/guides/testpmd_app_ug/testpmd_funcs.html#flow-rules-management
>
> There was also a useful talk abound HW rules debugging on DPDK Summit:
>
>
> https://dpdksummit2024.sched.com/event/1iAtU/debug-functional-and-performance-issues-in-rteflow-dariusz-sosnowski-nvidia-corp
>
>
[-- Attachment #2: Type: text/html, Size: 61617 bytes --]
next prev parent reply other threads:[~2025-02-03 13:52 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-01-28 16:54 Sid ali cherrati
2025-01-28 18:46 ` Dmitry Kozlyuk
2025-02-03 13:51 ` Sid ali cherrati [this message]
2025-02-03 15:00 ` Dmitry Kozlyuk
2025-02-03 15:05 ` Sid ali cherrati
2025-02-03 17:12 ` Sid ali cherrati
2025-02-04 9:28 ` Dariusz Sosnowski
2025-02-04 15:41 ` Medvedkin, Vladimir
2025-02-04 15:50 ` Sid ali cherrati
2025-02-04 17:41 ` Medvedkin, Vladimir
2025-01-28 18:47 ` Stephen Hemminger
-- strict thread matches above, loose matches on Subject: below --
2025-01-28 16:50 Sid ali cherrati
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to='CALn3+CN_nk0GsFyMoC_VVSkTZ2XaS4=T93-h86tR+RT3sDnn7w@mail.gmail.com' \
--to=scherrati1@gmail.com \
--cc=dmitry.kozliuk@gmail.com \
--cc=users@dpdk.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).