* DPDK Flow Filtering Not Working as Expected @ 2025-01-28 16:54 Sid ali cherrati 2025-01-28 18:46 ` Dmitry Kozlyuk 2025-01-28 18:47 ` Stephen Hemminger 0 siblings, 2 replies; 12+ messages in thread From: Sid ali cherrati @ 2025-01-28 16:54 UTC (permalink / raw) To: users [-- Attachment #1: Type: text/plain, Size: 2770 bytes --] Dear DPDK Team, 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: 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; struct rte_flow_item pattern[4]; // 4 pour inclure END struct rte_flow_action action[2]; struct rte_flow *flow; // Remplir l'attribut de la règle memset(&attr, 0, sizeof(struct rte_flow_attr)); attr.ingress = 1; // Règle pour le trafic entrant attr.priority = 1000; // Priorité haute pour que cette règle soit appliquée en premier // Définir le motif de filtrage (IP + UDP) memset(pattern, 0, sizeof(pattern)); pattern[0].type = RTE_FLOW_ITEM_TYPE_ETH; // Motif IPv4 pattern[1].type = RTE_FLOW_ITEM_TYPE_IPV4; pattern[1].spec = &(struct rte_flow_item_ipv4){ .hdr = { .dst_addr = RTE_BE32(ip_addr), // Adresse IP de destination } }; pattern[1].mask = &(struct rte_flow_item_ipv4){ .hdr = { .dst_addr = RTE_BE32(0xFFFFFFFF), // Masque pour l'adresse IP } }; // Motif UDP pattern[2].type = RTE_FLOW_ITEM_TYPE_UDP; pattern[2].spec = &(struct rte_flow_item_udp){ .hdr = { .dst_port = RTE_BE16(udp_port), // Port de destination } }; pattern[2].mask = &(struct rte_flow_item_udp){ .hdr = { .dst_port = RTE_BE16(0xFFFF), // Masque pour le port } }; // Fin du motif pattern[3].type = RTE_FLOW_ITEM_TYPE_END; // Définir l'action (accepter le paquet) memset(action, 0, sizeof(action)); // Envoyer à la file RX_ID action[0].type = RTE_FLOW_ACTION_TYPE_QUEUE; action[0].conf = &(struct rte_flow_action_queue){ .index = RX_ID, // Envoyer les paquets à la file RX_ID }; // Fin de la liste d'actions action[1].type = RTE_FLOW_ACTION_TYPE_END; // Créer la règle de filtrage flow = rte_flow_create(port_id, &attr, pattern, action, &error); if (flow == NULL) { printf("Erreur lors de la création de la règle de filtrage : %s\n", error. message); return -1; } // Afficher un message de succès printf( "Règle de filtrage créee avec succès pour l'IP %u.%u.%u.%u et le port %u\n", (ip_addr >> 24) & 0xFF, (ip_addr >> 16) & 0xFF, (ip_addr >> 8) & 0xFF, ip_addr & 0xFF, udp_port ); return 0; } However, despite this configuration, I continue to receive packets with other IP addresses and ports that do not match the specified filter. 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. Thank you for your assistance. Best regards, Ali [-- Attachment #2: Type: text/html, Size: 24550 bytes --] ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: DPDK Flow Filtering Not Working as Expected 2025-01-28 16:54 DPDK Flow Filtering Not Working as Expected Sid ali cherrati @ 2025-01-28 18:46 ` Dmitry Kozlyuk 2025-02-03 13:51 ` Sid ali cherrati 2025-01-28 18:47 ` Stephen Hemminger 1 sibling, 1 reply; 12+ messages in thread From: Dmitry Kozlyuk @ 2025-01-28 18:46 UTC (permalink / raw) To: Sid ali cherrati; +Cc: users 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 ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: DPDK Flow Filtering Not Working as Expected 2025-01-28 18:46 ` Dmitry Kozlyuk @ 2025-02-03 13:51 ` Sid ali cherrati 2025-02-03 15:00 ` Dmitry Kozlyuk 0 siblings, 1 reply; 12+ messages in thread From: Sid ali cherrati @ 2025-02-03 13:51 UTC (permalink / raw) To: Dmitry Kozlyuk; +Cc: users [-- 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 --] ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: DPDK Flow Filtering Not Working as Expected 2025-02-03 13:51 ` Sid ali cherrati @ 2025-02-03 15:00 ` Dmitry Kozlyuk 2025-02-03 15:05 ` Sid ali cherrati 0 siblings, 1 reply; 12+ messages in thread From: Dmitry Kozlyuk @ 2025-02-03 15:00 UTC (permalink / raw) To: Sid ali cherrati; +Cc: users 2025-02-03 14:51 (UTC+0100), Sid ali cherrati: > [...] > 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; > } > [...] > 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? There is no this exact error text in your code or DPDK, I assume we're talking about the quoted fragment. `flow` is a pointer, the correct error condition is `if (flow == NULL)`, so your code probably misinterprets success as error. Also `flow` is not assigned if `rte_flow_validate()` returns non-0. ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: DPDK Flow Filtering Not Working as Expected 2025-02-03 15:00 ` Dmitry Kozlyuk @ 2025-02-03 15:05 ` Sid ali cherrati 2025-02-03 17:12 ` Sid ali cherrati 0 siblings, 1 reply; 12+ messages in thread From: Sid ali cherrati @ 2025-02-03 15:05 UTC (permalink / raw) To: Dmitry Kozlyuk; +Cc: users [-- Attachment #1: Type: text/plain, Size: 4157 bytes --] I pointed where the error is occurring on the code below : #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; } 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) { // Its happening Here <--- !!! ---> printf("Erreur création règle DROP: %s (Type: %d, Cause: %p)\n", error.message, error.type, error.cause); return -1; } printf("Default drop rule created successfully.\n"); return 0; } Here is what it returns : > EAL: Detected CPU lcores: 6 > EAL: Detected NUMA nodes: 1 > EAL: Detected shared linkage of DPDK > EAL: Multi-process socket /var/run/dpdk/rte/mp_socket > EAL: Selected IOVA mode 'VA' > EAL: VFIO support initialized > EAL: Using IOMMU type 1 (Type 1) > Port 0 initialisé avec succès > Capacités de la NIC (port 0): > - Groupes supportés : 232756 > - Actions supportées : 9a69f > Règle de flux créée avec succès pour IP 10.81.16.111 et port UDP 1234 > Erreur création règle DROP: Not supported action. (Type: 16, Cause: > 0x7ffe87ef63e0) > EAL: Error - exiting with code: 1 > Erreur création règle drop-all > Le lun. 3 févr. 2025 à 16:00, Dmitry Kozlyuk <dmitry.kozliuk@gmail.com> a écrit : > 2025-02-03 14:51 (UTC+0100), Sid ali cherrati: > > [...] > > 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; > > } > > [...] > > 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? > > There is no this exact error text in your code or DPDK, > I assume we're talking about the quoted fragment. > `flow` is a pointer, the correct error condition is `if (flow == NULL)`, > so your code probably misinterprets success as error. > Also `flow` is not assigned if `rte_flow_validate()` returns non-0. > [-- Attachment #2: Type: text/html, Size: 33408 bytes --] ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: DPDK Flow Filtering Not Working as Expected 2025-02-03 15:05 ` Sid ali cherrati @ 2025-02-03 17:12 ` Sid ali cherrati 2025-02-04 9:28 ` Dariusz Sosnowski 0 siblings, 1 reply; 12+ messages in thread From: Sid ali cherrati @ 2025-02-03 17:12 UTC (permalink / raw) To: Dmitry Kozlyuk; +Cc: users [-- Attachment #1: Type: text/plain, Size: 7059 bytes --] Here is a better version of the code : #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 == NULL) { printf("Erreur lors de la création de la règle de flux : %s\n", error. message); return -1; } 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 = NULL; struct rte_flow_error error; pattern[0].type = RTE_FLOW_ITEM_TYPE_ETH; pattern[1].type = RTE_FLOW_ITEM_TYPE_END; // Actions actions[0].type = RTE_FLOW_ACTION_TYPE_DROP; actions[0].conf = NULL; actions[1].type = RTE_FLOW_ACTION_TYPE_END; // Validation & Création if (rte_flow_validate(port_id, &attr, pattern, actions, &error) != 0) { printf("Échec validation: %s\n", error.message); return -1; } flow = rte_flow_create(port_id, &attr, pattern, actions, &error); if (flow == NULL) { printf("Échec création: %s\n", error.message); return -1; } printf("Règle DROP créée.\n"); return 0; } Le lun. 3 févr. 2025 à 16:05, Sid ali cherrati <scherrati1@gmail.com> a écrit : > I pointed where the error is occurring on the code below : > > #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; > } > > 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) { // Its happening Here <--- !!! ---> > printf("Erreur création règle DROP: %s (Type: %d, Cause: %p)\n", > error.message, error.type, error.cause); > return -1; > } > > printf("Default drop rule created successfully.\n"); > return 0; > } > > Here is what it returns : > >> EAL: Detected CPU lcores: 6 >> EAL: Detected NUMA nodes: 1 >> EAL: Detected shared linkage of DPDK >> EAL: Multi-process socket /var/run/dpdk/rte/mp_socket >> EAL: Selected IOVA mode 'VA' >> EAL: VFIO support initialized >> EAL: Using IOMMU type 1 (Type 1) >> Port 0 initialisé avec succès >> Capacités de la NIC (port 0): >> - Groupes supportés : 232756 >> - Actions supportées : 9a69f >> Règle de flux créée avec succès pour IP 10.81.16.111 et port UDP 1234 >> Erreur création règle DROP: Not supported action. (Type: 16, Cause: >> 0x7ffe87ef63e0) >> EAL: Error - exiting with code: 1 >> Erreur création règle drop-all >> > > Le lun. 3 févr. 2025 à 16:00, Dmitry Kozlyuk <dmitry.kozliuk@gmail.com> a > écrit : > >> 2025-02-03 14:51 (UTC+0100), Sid ali cherrati: >> > [...] >> > 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; >> > } >> > [...] >> > 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? >> >> There is no this exact error text in your code or DPDK, >> I assume we're talking about the quoted fragment. >> `flow` is a pointer, the correct error condition is `if (flow == NULL)`, >> so your code probably misinterprets success as error. >> Also `flow` is not assigned if `rte_flow_validate()` returns non-0. >> > [-- Attachment #2: Type: text/html, Size: 66348 bytes --] ^ permalink raw reply [flat|nested] 12+ messages in thread
* RE: DPDK Flow Filtering Not Working as Expected 2025-02-03 17:12 ` Sid ali cherrati @ 2025-02-04 9:28 ` Dariusz Sosnowski 2025-02-04 15:41 ` Medvedkin, Vladimir 0 siblings, 1 reply; 12+ messages in thread From: Dariusz Sosnowski @ 2025-02-04 9:28 UTC (permalink / raw) To: Sid ali cherrati, Dmitry Kozlyuk, Anatoly Burakov, Vladimir Medvedkin Cc: users Hi, Anatoly, Vladimir - Would you be able to help with the issue regarding DROP action not being supported on X540-AT2? Best regards, Dariusz Sosnowski > From: Sid ali cherrati <scherrati1@gmail.com> > Sent: Monday, February 3, 2025 18:12 > To: Dmitry Kozlyuk <dmitry.kozliuk@gmail.com> > Cc: users@dpdk.org > Subject: Re: DPDK Flow Filtering Not Working as Expected > > External email: Use caution opening links or attachments > > Here is a better version of the code : > > #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 > == > NULL) { > > printf("Erreur lors de la création de la règle de flux : > %s\n", > error.message); > > return > -1; > > } > > > > 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 > = > NULL; > > struct > rte_flow_error > error; > > > > pattern[0].type > = > RTE_FLOW_ITEM_TYPE_ETH; > > pattern[1].type > = > RTE_FLOW_ITEM_TYPE_END; > > > > // Actions > > actions[0].type > = > RTE_FLOW_ACTION_TYPE_DROP; > > actions[0].conf > = > NULL; > > actions[1].type > = > RTE_FLOW_ACTION_TYPE_END; > > > > // Validation & Création > > if (rte_flow_validate(port_id, > &attr, > pattern, > actions, > &error) > != > 0) { > > printf("Échec validation: > %s\n", > error.message); > > return > -1; > > } > > > > flow > = > rte_flow_create(port_id, > &attr, > pattern, > actions, > &error); > > if (flow > == > NULL) { > > printf("Échec création: > %s\n", > error.message); > > return > -1; > > } > > > > printf("Règle DROP créée.\n"); > > return > 0; > > } > > > > > > > Le lun. 3 févr. 2025 à 16:05, Sid ali cherrati <mailto:scherrati1@gmail.com> a écrit : > I pointed where the error is occurring on the code below : > #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; > } > > 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) { // Its happening Here <--- !!! ---> > printf("Erreur création règle DROP: %s (Type: %d, Cause: %p)\n", > error.message, error.type, error.cause); > return -1; > } > > printf("Default drop rule created successfully.\n"); > return 0; > } > > Here is what it returns : > EAL: Detected CPU lcores: 6 > EAL: Detected NUMA nodes: 1 > EAL: Detected shared linkage of DPDK > EAL: Multi-process socket /var/run/dpdk/rte/mp_socket > EAL: Selected IOVA mode 'VA' > EAL: VFIO support initialized > EAL: Using IOMMU type 1 (Type 1) > Port 0 initialisé avec succès > Capacités de la NIC (port 0): > - Groupes supportés : 232756 > - Actions supportées : 9a69f > Règle de flux créée avec succès pour IP 10.81.16.111 et port UDP 1234 > Erreur création règle DROP: Not supported action. (Type: 16, Cause: 0x7ffe87ef63e0) > EAL: Error - exiting with code: 1 > Erreur création règle drop-all > > Le lun. 3 févr. 2025 à 16:00, Dmitry Kozlyuk <mailto:dmitry.kozliuk@gmail.com> a écrit : > 2025-02-03 14:51 (UTC+0100), Sid ali cherrati: > > [...] > > 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; > > } > > [...] > > 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? > > There is no this exact error text in your code or DPDK, > I assume we're talking about the quoted fragment. > `flow` is a pointer, the correct error condition is `if (flow == NULL)`, > so your code probably misinterprets success as error. > Also `flow` is not assigned if `rte_flow_validate()` returns non-0. ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: DPDK Flow Filtering Not Working as Expected 2025-02-04 9:28 ` Dariusz Sosnowski @ 2025-02-04 15:41 ` Medvedkin, Vladimir 2025-02-04 15:50 ` Sid ali cherrati 0 siblings, 1 reply; 12+ messages in thread From: Medvedkin, Vladimir @ 2025-02-04 15:41 UTC (permalink / raw) To: Dariusz Sosnowski, Sid ali cherrati, Dmitry Kozlyuk, Anatoly Burakov Cc: users Hi all, The goal that Ali is trying to achieve is not possible with the X540-AT2 NIC (as with any other ixgbe NIC). The problem is related to: 1. The first rule is processed by the FDIR engine 2. FDIR engine is executed in the HW pipeline almost in the end (just before RSS), i.e. after other filters that we could use to match all other packets (5tuple filter engine in this particular case). Therefore my recommendations here would be to use a modern NIC such as E810 to implement the required filtering logic. On 04/02/2025 09:28, Dariusz Sosnowski wrote: > Hi, > > Anatoly, Vladimir - Would you be able to help with the issue regarding DROP action not being supported on X540-AT2? > > Best regards, > Dariusz Sosnowski > >> From: Sid ali cherrati <scherrati1@gmail.com> >> Sent: Monday, February 3, 2025 18:12 >> To: Dmitry Kozlyuk <dmitry.kozliuk@gmail.com> >> Cc: users@dpdk.org >> Subject: Re: DPDK Flow Filtering Not Working as Expected >> >> External email: Use caution opening links or attachments >> >> Here is a better version of the code : >> <snip> >> >> Le lun. 3 févr. 2025 à 16:00, Dmitry Kozlyuk <mailto:dmitry.kozliuk@gmail.com> a écrit : >> 2025-02-03 14:51 (UTC+0100), Sid ali cherrati: >>> [...] >>> 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; >>> } >>> [...] >>> 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? >> There is no this exact error text in your code or DPDK, >> I assume we're talking about the quoted fragment. >> `flow` is a pointer, the correct error condition is `if (flow == NULL)`, >> so your code probably misinterprets success as error. >> Also `flow` is not assigned if `rte_flow_validate()` returns non-0. -- Regards, Vladimir ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: DPDK Flow Filtering Not Working as Expected 2025-02-04 15:41 ` Medvedkin, Vladimir @ 2025-02-04 15:50 ` Sid ali cherrati 2025-02-04 17:41 ` Medvedkin, Vladimir 0 siblings, 1 reply; 12+ messages in thread From: Sid ali cherrati @ 2025-02-04 15:50 UTC (permalink / raw) To: Medvedkin, Vladimir Cc: Dariusz Sosnowski, Dmitry Kozlyuk, Anatoly Burakov, users [-- Attachment #1: Type: text/plain, Size: 2398 bytes --] Hello Vladimir, Thank you for the clarification. I'll try using the E810 and provide an update on the issue. Best regards, Ali Le mar. 4 févr. 2025 à 16:41, Medvedkin, Vladimir < vladimir.medvedkin@intel.com> a écrit : > Hi all, > > The goal that Ali is trying to achieve is not possible with the X540-AT2 > NIC (as with any other ixgbe NIC). The problem is related to: > > 1. The first rule is processed by the FDIR engine > > 2. FDIR engine is executed in the HW pipeline almost in the end (just > before RSS), i.e. after other filters that we could use to match all > other packets (5tuple filter engine in this particular case). > > Therefore my recommendations here would be to use a modern NIC such as > E810 to implement the required filtering logic. > > On 04/02/2025 09:28, Dariusz Sosnowski wrote: > > Hi, > > > > Anatoly, Vladimir - Would you be able to help with the issue regarding > DROP action not being supported on X540-AT2? > > > > Best regards, > > Dariusz Sosnowski > > > >> From: Sid ali cherrati <scherrati1@gmail.com> > >> Sent: Monday, February 3, 2025 18:12 > >> To: Dmitry Kozlyuk <dmitry.kozliuk@gmail.com> > >> Cc: users@dpdk.org > >> Subject: Re: DPDK Flow Filtering Not Working as Expected > >> > >> External email: Use caution opening links or attachments > >> > >> Here is a better version of the code : > >> > <snip> > >> > >> Le lun. 3 févr. 2025 à 16:00, Dmitry Kozlyuk <mailto: > dmitry.kozliuk@gmail.com> a écrit : > >> 2025-02-03 14:51 (UTC+0100), Sid ali cherrati: > >>> [...] > >>> 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; > >>> } > >>> [...] > >>> 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? > >> There is no this exact error text in your code or DPDK, > >> I assume we're talking about the quoted fragment. > >> `flow` is a pointer, the correct error condition is `if (flow == NULL)`, > >> so your code probably misinterprets success as error. > >> Also `flow` is not assigned if `rte_flow_validate()` returns non-0. > > -- > Regards, > Vladimir > > [-- Attachment #2: Type: text/html, Size: 3395 bytes --] ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: DPDK Flow Filtering Not Working as Expected 2025-02-04 15:50 ` Sid ali cherrati @ 2025-02-04 17:41 ` Medvedkin, Vladimir 0 siblings, 0 replies; 12+ messages in thread From: Medvedkin, Vladimir @ 2025-02-04 17:41 UTC (permalink / raw) To: Sid ali cherrati Cc: Dariusz Sosnowski, Dmitry Kozlyuk, Anatoly Burakov, users [-- Attachment #1: Type: text/plain, Size: 3353 bytes --] You can also try with the existing X540-AT2 NIC the following : - Init NIC with 2 queues - set the FDIR flow for your particular ip/port to route your packet to a queue number, say 1 - Instead of using rte_flow to drop all other packets, use RSS. Rewrite the RSS ReTa (see rte_eth_dev_rss_reta_update) with queue id you are not going to poll, so in this case with queue id = 0. All ReTa entries will be 0, so packets not matched with the FDIR will be assigned to this queue. - ignore rx on the queue 0 I believe this approach would be better for your particular use case, than relying on rte_flow to drop all the traffic, which, as we could see, depends on the internal HW implementation. On 04/02/2025 15:50, Sid ali cherrati wrote: > > Hello Vladimir, > > Thank you for the clarification. > > I'll try using the E810 and provide an update on the issue. > > Best regards, > Ali > > > Le mar. 4 févr. 2025 à 16:41, Medvedkin, Vladimir > <vladimir.medvedkin@intel.com> a écrit : > > Hi all, > > The goal that Ali is trying to achieve is not possible with the > X540-AT2 > NIC (as with any other ixgbe NIC). The problem is related to: > > 1. The first rule is processed by the FDIR engine > > 2. FDIR engine is executed in the HW pipeline almost in the end (just > before RSS), i.e. after other filters that we could use to match all > other packets (5tuple filter engine in this particular case). > > Therefore my recommendations here would be to use a modern NIC > such as > E810 to implement the required filtering logic. > > On 04/02/2025 09:28, Dariusz Sosnowski wrote: > > Hi, > > > > Anatoly, Vladimir - Would you be able to help with the issue > regarding DROP action not being supported on X540-AT2? > > > > Best regards, > > Dariusz Sosnowski > > > >> From: Sid ali cherrati <scherrati1@gmail.com> > >> Sent: Monday, February 3, 2025 18:12 > >> To: Dmitry Kozlyuk <dmitry.kozliuk@gmail.com> > >> Cc: users@dpdk.org > >> Subject: Re: DPDK Flow Filtering Not Working as Expected > >> > >> External email: Use caution opening links or attachments > >> > >> Here is a better version of the code : > >> > <snip> > >> > >> Le lun. 3 févr. 2025 à 16:00, Dmitry Kozlyuk > <mailto:dmitry.kozliuk@gmail.com> a écrit : > >> 2025-02-03 14:51 (UTC+0100), Sid ali cherrati: > >>> [...] > >>> 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; > >>> } > >>> [...] > >>> 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? > >> There is no this exact error text in your code or DPDK, > >> I assume we're talking about the quoted fragment. > >> `flow` is a pointer, the correct error condition is `if (flow > == NULL)`, > >> so your code probably misinterprets success as error. > >> Also `flow` is not assigned if `rte_flow_validate()` returns non-0. > > -- > Regards, > Vladimir > -- Regards, Vladimir [-- Attachment #2: Type: text/html, Size: 5959 bytes --] ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: DPDK Flow Filtering Not Working as Expected 2025-01-28 16:54 DPDK Flow Filtering Not Working as Expected Sid ali cherrati 2025-01-28 18:46 ` Dmitry Kozlyuk @ 2025-01-28 18:47 ` Stephen Hemminger 1 sibling, 0 replies; 12+ messages in thread From: Stephen Hemminger @ 2025-01-28 18:47 UTC (permalink / raw) To: Sid ali cherrati; +Cc: users On Tue, 28 Jan 2025 17:54:40 +0100 Sid ali cherrati <scherrati1@gmail.com> wrote: > Dear DPDK Team, > > 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: > 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; > struct rte_flow_item pattern[4]; // 4 pour inclure END > struct rte_flow_action action[2]; > struct rte_flow *flow; > > // Remplir l'attribut de la règle > memset(&attr, 0, sizeof(struct rte_flow_attr)); > attr.ingress = 1; // Règle pour le trafic entrant > attr.priority = 1000; // Priorité haute pour que cette règle soit appliquée > en premier > > // Définir le motif de filtrage (IP + UDP) > memset(pattern, 0, sizeof(pattern)); > > pattern[0].type = RTE_FLOW_ITEM_TYPE_ETH; > > // Motif IPv4 > pattern[1].type = RTE_FLOW_ITEM_TYPE_IPV4; > pattern[1].spec = &(struct rte_flow_item_ipv4){ > .hdr = { > .dst_addr = RTE_BE32(ip_addr), // Adresse IP de destination > } > }; > pattern[1].mask = &(struct rte_flow_item_ipv4){ > .hdr = { > .dst_addr = RTE_BE32(0xFFFFFFFF), // Masque pour l'adresse IP > } > }; > > // Motif UDP > pattern[2].type = RTE_FLOW_ITEM_TYPE_UDP; > pattern[2].spec = &(struct rte_flow_item_udp){ > .hdr = { > .dst_port = RTE_BE16(udp_port), // Port de destination > } > }; > pattern[2].mask = &(struct rte_flow_item_udp){ > .hdr = { > .dst_port = RTE_BE16(0xFFFF), // Masque pour le port > } > }; > > // Fin du motif > pattern[3].type = RTE_FLOW_ITEM_TYPE_END; > > // Définir l'action (accepter le paquet) > memset(action, 0, sizeof(action)); > > // Envoyer à la file RX_ID > action[0].type = RTE_FLOW_ACTION_TYPE_QUEUE; > action[0].conf = &(struct rte_flow_action_queue){ > .index = RX_ID, // Envoyer les paquets à la file RX_ID > }; > > // Fin de la liste d'actions > action[1].type = RTE_FLOW_ACTION_TYPE_END; > > // Créer la règle de filtrage > flow = rte_flow_create(port_id, &attr, pattern, action, &error); > if (flow == NULL) { > printf("Erreur lors de la création de la règle de filtrage : %s\n", error. > message); > return -1; > } > > // Afficher un message de succès > printf( > "Règle de filtrage créee avec succès pour l'IP %u.%u.%u.%u et le port %u\n", > (ip_addr >> 24) & 0xFF, > (ip_addr >> 16) & 0xFF, > (ip_addr >> 8) & 0xFF, > ip_addr & 0xFF, > udp_port > ); > > return 0; > } > > However, despite this configuration, I continue to receive packets with > other IP addresses and ports that do not match the specified filter. > > 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. > > Thank you for your assistance. > > Best regards, > > Ali You need to add a wildcard flow filter (ie match all) with with a drop action. The default when no matches to any flow is process packet as normal using default queues. ^ permalink raw reply [flat|nested] 12+ messages in thread
* DPDK Flow Filtering Not Working as Expected @ 2025-01-28 16:50 Sid ali cherrati 0 siblings, 0 replies; 12+ messages in thread From: Sid ali cherrati @ 2025-01-28 16:50 UTC (permalink / raw) To: users [-- Attachment #1: Type: text/plain, Size: 2770 bytes --] Dear DPDK Team, 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: 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; struct rte_flow_item pattern[4]; // 4 pour inclure END struct rte_flow_action action[2]; struct rte_flow *flow; // Remplir l'attribut de la règle memset(&attr, 0, sizeof(struct rte_flow_attr)); attr.ingress = 1; // Règle pour le trafic entrant attr.priority = 1000; // Priorité haute pour que cette règle soit appliquée en premier // Définir le motif de filtrage (IP + UDP) memset(pattern, 0, sizeof(pattern)); pattern[0].type = RTE_FLOW_ITEM_TYPE_ETH; // Motif IPv4 pattern[1].type = RTE_FLOW_ITEM_TYPE_IPV4; pattern[1].spec = &(struct rte_flow_item_ipv4){ .hdr = { .dst_addr = RTE_BE32(ip_addr), // Adresse IP de destination } }; pattern[1].mask = &(struct rte_flow_item_ipv4){ .hdr = { .dst_addr = RTE_BE32(0xFFFFFFFF), // Masque pour l'adresse IP } }; // Motif UDP pattern[2].type = RTE_FLOW_ITEM_TYPE_UDP; pattern[2].spec = &(struct rte_flow_item_udp){ .hdr = { .dst_port = RTE_BE16(udp_port), // Port de destination } }; pattern[2].mask = &(struct rte_flow_item_udp){ .hdr = { .dst_port = RTE_BE16(0xFFFF), // Masque pour le port } }; // Fin du motif pattern[3].type = RTE_FLOW_ITEM_TYPE_END; // Définir l'action (accepter le paquet) memset(action, 0, sizeof(action)); // Envoyer à la file RX_ID action[0].type = RTE_FLOW_ACTION_TYPE_QUEUE; action[0].conf = &(struct rte_flow_action_queue){ .index = RX_ID, // Envoyer les paquets à la file RX_ID }; // Fin de la liste d'actions action[1].type = RTE_FLOW_ACTION_TYPE_END; // Créer la règle de filtrage flow = rte_flow_create(port_id, &attr, pattern, action, &error); if (flow == NULL) { printf("Erreur lors de la création de la règle de filtrage : %s\n", error. message); return -1; } // Afficher un message de succès printf( "Règle de filtrage créee avec succès pour l'IP %u.%u.%u.%u et le port %u\n", (ip_addr >> 24) & 0xFF, (ip_addr >> 16) & 0xFF, (ip_addr >> 8) & 0xFF, ip_addr & 0xFF, udp_port ); return 0; } However, despite this configuration, I continue to receive packets with other IP addresses and ports that do not match the specified filter. 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. Thank you for your assistance. Best regards, Ali [-- Attachment #2: Type: text/html, Size: 24542 bytes --] ^ permalink raw reply [flat|nested] 12+ messages in thread
end of thread, other threads:[~2025-02-04 17:41 UTC | newest] Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2025-01-28 16:54 DPDK Flow Filtering Not Working as Expected Sid ali cherrati 2025-01-28 18:46 ` Dmitry Kozlyuk 2025-02-03 13:51 ` Sid ali cherrati 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
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).