From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 708B94625D for ; Tue, 18 Feb 2025 14:26:11 +0100 (CET) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 3CFAB402C4; Tue, 18 Feb 2025 14:26:11 +0100 (CET) Received: from mail-yb1-f181.google.com (mail-yb1-f181.google.com [209.85.219.181]) by mails.dpdk.org (Postfix) with ESMTP id A8D22402A0 for ; Tue, 18 Feb 2025 14:26:09 +0100 (CET) Received: by mail-yb1-f181.google.com with SMTP id 3f1490d57ef6-e4930eca0d4so3878988276.3 for ; Tue, 18 Feb 2025 05:26:09 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1739885169; x=1740489969; darn=dpdk.org; h=to:subject:message-id:date:from:mime-version:from:to:cc:subject :date:message-id:reply-to; bh=5LSJ6iLSkDTAPgmJC4EYyH/2CkJmnm4CCUIGwn7tXPU=; b=RlJ1l6AdhnCcddod40ahGDkOjHiIpiaeJEMurqrJNGcdy3Pme0aPEForr/QOzyfSM6 EBFCZipKPgEHZUb2dQkNhdZKwF43ykAZu1DaHxdz+LsfTKiYSg/ReGCJO/88K0VmaH7a ikdoACGjPxJ6x93PZTfcZc98u23LLDNl8uN+04tKQLxcvZIcK8atFJ4npOM+6LvjGL8m aO+ggmH9CpRO+aXvrji+dW9qWXZDqyPP6UrFYHpSwsoEDxGLsohpGf+i0HizPcL75Y6E 7Z2HpX7j6Feo7TuYaxepFDz6U/BAM0CFm6E06NlxpzH+A2rFXuF+DhkMbfqt8JhYtiuh GthQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1739885169; x=1740489969; h=to:subject:message-id:date:from:mime-version:x-gm-message-state :from:to:cc:subject:date:message-id:reply-to; bh=5LSJ6iLSkDTAPgmJC4EYyH/2CkJmnm4CCUIGwn7tXPU=; b=k7hAKi55I2JtFwRFdAoclvxsOHss494OOLUdPs/7kWp6J4SS7QWPLBdX4/dMQ5fWiO QIN2e0vX/L/ouJ+dHvgxnKiakMGSZ3jxdAWVguxFEK2LDVhUBqnChNvgiEISifSw/my3 uO5su2GZJM4e4xoOn7WkPmY3p6iZNLQvuMwbIG19wIu9o5DNzLZqWjH/9Te9KiMeV1zk /64N0CdmBF/0wnY1Ry4gPDqJ79eZMbvpGor1/f82mXkzIW+RDxLrOUrC8gv2uqXnKTU3 0zpnLPNAefyQR2Sfi7JF9XpJtrjKBJNi/60+Gq5/qo2m5lCkEQtHMGUER2i+GwUxgb1k 6MSQ== X-Gm-Message-State: AOJu0Yz/iFVyNGW7obF1FnmjWNlJTJz/gwQtUotn+Vw6Bfift+t2KE2F MWAFQi3WU/NCGjrnfSZU/dW/9TO385YF3cuLW2h7HSjkpYjm0JgQwpjT1ZOasyTU/ZoMQDeYWyG u9lkSd4rgb7BAqxo4l/wI2mj+nAoCKTPJ X-Gm-Gg: ASbGncu49781LuiKZpG1Dcck3mJUk6SnTE4gX4jpP0m++T3zFSAh9y7sA4DkLZzUGQd YbQMn60UwBKQ9+91S71qlk9W9n5VB2lhGVl2M9xnzsm9ezQCcwEg7XcseX/MoHT+vjEmG1ybeSg == X-Google-Smtp-Source: AGHT+IE/3h+31nt69M1LBNULjbnOERUYWhm5Sh8kF/LIJlMbyYAIxI6JDn+ZcR7W2VQE/xiNq7Qa2NOYX8q88OsO1Ss= X-Received: by 2002:a05:6902:1b91:b0:e5d:b9a0:a14a with SMTP id 3f1490d57ef6-e5dc9067229mr9248557276.24.1739885168595; Tue, 18 Feb 2025 05:26:08 -0800 (PST) MIME-Version: 1.0 From: Sid ali cherrati Date: Tue, 18 Feb 2025 14:25:56 +0100 X-Gm-Features: AWEUYZnxCsDf535qCOQqfGTsfdhLPVz0F3J4YW7zY3cOpijsFiz1hNb1kbpkglI Message-ID: Subject: Packets Not Received After Redirection To: users@dpdk.org Content-Type: multipart/alternative; boundary="0000000000006c9a54062e6a956d" X-BeenThere: users@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK usage discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: users-bounces@dpdk.org --0000000000006c9a54062e6a956d Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable Dear DPDK Team, I am using DPDK 23.11 with an X540-AT (ixgbe) NIC. I am facing an issue where this card is not compatible with a combination of two flow rules. To work around this, I attempted to create a single rule to redirect packets that match specific criteria to, let's say, queue 5. Initially, this works for a few packets, but after that, no more packets are received. I am unsure whether this issue is related to the interrupts (though I=E2=80= =99ve tested without interrupts and the problem persists) or not. I also thought that if queue 0 is full (since the drop rule is not functioning), the filter might stop working, so I tried clearing the queue to see if it would resolve the issue. However, even after that, the problem remains. I am new to DPDK, so please let me know if I am doing something wrong or if there are any suggestions to address this issue. Below is the code I have implemented: #include "../include/flow.h" #include "../include/port.h" #include #include 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 =3D { .ingress =3D 1, .priority =3D 0 }; struct rte_flow_item pattern[4]; struct rte_flow_action action[2]; struct rte_flow *flow; // D=C3=A9finir le motif Ethernet memset(pattern, 0, sizeof(pattern)); pattern[0].type =3D RTE_FLOW_ITEM_TYPE_ETH; // D=C3=A9finir le motif IPv4 struct rte_flow_item_ipv4 ipv4_spec =3D { .hdr.dst_addr =3D RTE_BE32(ip_add= r) }; struct rte_flow_item_ipv4 ipv4_mask =3D { .hdr.dst_addr =3D RTE_BE32(0xFFFF= FFFF) }; pattern[1].type =3D RTE_FLOW_ITEM_TYPE_IPV4; pattern[1].spec =3D &ipv4_spec; pattern[1].mask =3D &ipv4_mask; // D=C3=A9finir le motif UDP struct rte_flow_item_udp udp_spec =3D { .hdr.dst_port =3D RTE_BE16(udp_port= ) }; struct rte_flow_item_udp udp_mask =3D { .hdr.dst_port =3D RTE_BE16(0xFFFF) = }; pattern[2].type =3D RTE_FLOW_ITEM_TYPE_UDP; pattern[2].spec =3D &udp_spec; pattern[2].mask =3D &udp_mask; // Terminer le motif pattern[3].type =3D RTE_FLOW_ITEM_TYPE_END; // D=C3=A9finir l'action action[0].type =3D RTE_FLOW_ACTION_TYPE_QUEUE; struct rte_flow_action_queue queue_action =3D { .index =3D RX_ID }; action[0].conf =3D &queue_action; action[1].type =3D RTE_FLOW_ACTION_TYPE_END; if (rte_flow_validate(port_id, &attr, pattern, action, &error) !=3D 0) { printf("=C3=89chec validation: %s\n", error.message); return -1; } // Cr=C3=A9er la r=C3=A8gle de flux flow =3D rte_flow_create(port_id, &attr, pattern, action, &error); if (flow =3D=3D NULL) { printf("Erreur lors de la cr=C3=A9ation de la r=C3=A8gle de flux : %s\n", e= rror. message); return -1; } printf("R=C3=A8gle de flux cr=C3=A9=C3=A9e avec succ=C3=A8s 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_error error; struct rte_flow_attr attr =3D { .ingress =3D 1, .priority =3D 1 }; struct rte_flow_item pattern[4]; struct rte_flow_action action[2]; struct rte_flow *flow; // D=C3=A9finir le motif Ethernet memset(pattern, 0, sizeof(pattern)); pattern[0].type =3D RTE_FLOW_ITEM_TYPE_ETH; // D=C3=A9finir le motif IPv4 struct rte_flow_item_ipv4 ipv4_spec; struct rte_flow_item_ipv4 ipv4_mask; pattern[1].type =3D RTE_FLOW_ITEM_TYPE_IPV4; pattern[1].spec =3D &ipv4_spec; pattern[1].mask =3D &ipv4_mask; // D=C3=A9finir le motif UDP struct rte_flow_item_udp udp_spec; struct rte_flow_item_udp udp_mask; pattern[2].type =3D RTE_FLOW_ITEM_TYPE_UDP; pattern[2].spec =3D &udp_spec; pattern[2].mask =3D &udp_mask; // Terminer le motif pattern[3].type =3D RTE_FLOW_ITEM_TYPE_END; // D=C3=A9finir l'action action[0].type =3D RTE_FLOW_ACTION_TYPE_DROP; struct rte_flow_action_queue queue_action; // temporary action[0].conf =3D &queue_action; action[1].type =3D RTE_FLOW_ACTION_TYPE_END; // Validation & Cr=C3=A9ation if (rte_flow_validate(port_id, &attr, pattern, action, &error) !=3D 0) { printf("=C3=89chec validation: %s\n", error.message); return -1; } flow =3D rte_flow_create(port_id, &attr, pattern, action, &error); if (flow =3D=3D NULL) { printf("=C3=89chec cr=C3=A9ation: %s\n", error.message); return -1; } printf("R=C3=A8gle DROP cr=C3=A9=C3=A9e.\n"); return 0; } #include "../include/port.h" #include #include // Configuration par d=C3=A9faut du port static struct rte_eth_conf port_conf =3D { .txmode =3D { .mq_mode =3D RTE_ETH_MQ_TX_NONE, }, .rxmode =3D { .offloads =3D RTE_ETH_RX_OFFLOAD_UDP_CKSUM | RTE_ETH_RX_OFFLOAD_IPV4_CKSUM, .mq_mode =3D RTE_ETH_MQ_RX_NONE, .max_lro_pkt_size =3D 9000, }, .intr_conf =3D { .rxq =3D 1, } }; int port_init(uint16_t port_id, struct rte_mempool *mbuf_pool) { int retval; struct rte_eth_dev_info dev_info; struct rte_eth_rxconf rxq_conf; struct rte_eth_txconf txq_conf; // Obtenir les informations sur le p=C3=A9riph=C3=A9rique retval =3D rte_eth_dev_info_get(port_id, &dev_info); if (retval !=3D 0) { return retval; } if (NUM_RX > dev_info.max_rx_queues) { printf("Erreur: NUM_RX d=C3=A9passe le maximum support=C3=A9 (%u)\n", dev_i= nfo. max_rx_queues); return -1; } // Configurer le p=C3=A9riph=C3=A9rique Ethernet retval =3D rte_eth_dev_configure(port_id, NUM_RX, NUM_TX, &port_conf); if (retval !=3D 0) { return retval; } // Configurer les queues RX rxq_conf =3D dev_info.default_rxconf; rxq_conf.offloads =3D port_conf.rxmode.offloads; for(int i =3D 0; i < NUM_RX; i++){ retval =3D rte_eth_rx_queue_setup(port_id, i, 128, rte_eth_dev_socket_id( port_id), &rxq_conf, mbuf_pool); if (retval < 0) { return retval; } } // Configurer les queues TX txq_conf =3D dev_info.default_txconf; txq_conf.offloads =3D port_conf.txmode.offloads; retval =3D rte_eth_tx_queue_setup(port_id, TX_ID, 128, rte_eth_dev_socket_i= d( port_id), &txq_conf); if (retval < 0) { return retval; } // D=C3=A9marrer le p=C3=A9riph=C3=A9rique Ethernet retval =3D rte_eth_dev_start(port_id); if (retval < 0) { return retval; } // Activer le mode promiscuous (facultatif) // rte_eth_promiscuous_enable(port_id); printf("Port %u initialis=C3=A9 avec succ=C3=A8s\n", port_id); return 0; } void port_cleanup(uint16_t port_id) { rte_eth_dev_stop(port_id); rte_eth_dev_close(port_id); printf("Port %u arr=C3=AAt=C3=A9 et nettoy=C3=A9\n", port_id); } void send_gratuitous_arp(uint16_t port_id, struct rte_mempool *mbuf_pool, const struct rte_ether_addr *local_mac, uint32_t local_ip) { struct rte_mbuf *mbuf =3D rte_pktmbuf_alloc(mbuf_pool); if (!mbuf) { fprintf(stderr, "Failed to allocate mbuf\n"); return; } const uint16_t pkt_size =3D sizeof(struct rte_ether_hdr) + sizeof(struct rte_arp_hdr); const uint16_t min_frame_size =3D 60; // Minimum Ethernet frame size withou= t FCS uint16_t padding =3D (pkt_size < min_frame_size) ? (min_frame_size - pkt_si= ze) : 0; char *pkt_data =3D rte_pktmbuf_append(mbuf, pkt_size + padding); if (!pkt_data) { fprintf(stderr, "Failed to append data in mbuf\n"); rte_pktmbuf_free(mbuf); return; } // Zero out padding space if (padding > 0) { memset(pkt_data + pkt_size, 0, padding); } // Ethernet Header struct rte_ether_hdr *eth_hdr =3D (struct rte_ether_hdr *)pkt_data; rte_ether_addr_copy(local_mac, ð_hdr->src_addr); memset(ð_hdr->dst_addr, 0xFF, RTE_ETHER_ADDR_LEN); // Broadcast MAC eth_hdr->ether_type =3D rte_cpu_to_be_16(RTE_ETHER_TYPE_ARP); // ARP Header struct rte_arp_hdr *arp_hdr =3D (struct rte_arp_hdr *)(pkt_data + sizeof( struct rte_ether_hdr)); arp_hdr->arp_hardware =3D rte_cpu_to_be_16(RTE_ARP_HRD_ETHER); arp_hdr->arp_protocol =3D rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4); arp_hdr->arp_hlen =3D RTE_ETHER_ADDR_LEN; arp_hdr->arp_plen =3D 4; arp_hdr->arp_opcode =3D rte_cpu_to_be_16(RTE_ARP_OP_REQUEST); // Correcting this to request // Sender MAC/IP rte_ether_addr_copy(local_mac, &arp_hdr->arp_data.arp_sha); arp_hdr->arp_data.arp_sip =3D rte_cpu_to_be_32(local_ip); // Target MAC/IP (ARP request with the same IP as source) memset(&arp_hdr->arp_data.arp_tha, 0, RTE_ETHER_ADDR_LEN); // Unknown target MAC arp_hdr->arp_data.arp_tip =3D rte_cpu_to_be_32(local_ip); // Target IP =3D = Our own IP // Transmit struct rte_mbuf *tx_pkts[1]; tx_pkts[0] =3D mbuf; uint16_t nb_tx =3D rte_eth_tx_burst(port_id, TX_ID, tx_pkts, 1); if (nb_tx < 1) { rte_pktmbuf_free(mbuf); printf("Failed to send Gratuitous ARP\n"); } else { printf("Gratuitous ARP sent successfully\n"); } } #include "../include/flow.h" #include "../include/port.h" #include #include #include #include #include #include #include #include #define MAX_PKT_BURST 32 #define IP_ADDR RTE_IPV4(10, 81, 16, 111) #define UDP_PORT 1234 void clear_rx_queue(uint16_t port_id, uint16_t rx_id) { struct rte_mbuf *bufs[MAX_PKT_BURST]; uint16_t nb_rx; while ((nb_rx =3D rte_eth_rx_burst(port_id, rx_id, bufs, MAX_PKT_BURST)) > = 0) { for (uint16_t i =3D 0; i < nb_rx; i++) { rte_pktmbuf_free(bufs[i]); } } } int main(int argc, char **argv) { struct rte_mempool *mbuf_pool; struct rte_ether_addr local_mac; struct rte_epoll_event event[1]; struct rte_flow_error error; int ret, n; // Initialize EAL ret =3D rte_eal_init(argc, argv); if (ret < 0) { rte_exit(EXIT_FAILURE, "EAL initialization failed\n"); } // Create mbuf pool mbuf_pool =3D rte_pktmbuf_pool_create("MBUF_POOL", NUM_MBUFS, MBUF_CACHE_SI= ZE, 0, RTE_MBUF_DEFAULT_BUF_SIZE, rte_socket_id()); if (mbuf_pool =3D=3D NULL) { rte_exit(EXIT_FAILURE, "Cannot create mbuf pool\n"); } // Initialize port if (port_init(PORT_ID, mbuf_pool) !=3D 0) { rte_exit(EXIT_FAILURE, "Port initialization failed\n"); } // Get MAC address ret =3D rte_eth_macaddr_get(PORT_ID, &local_mac); if(ret !=3D 0) { rte_exit(EXIT_FAILURE, "Failed to get MAC address\n"); } send_gratuitous_arp(PORT_ID, mbuf_pool, &local_mac, IP_ADDR); if (flow_filtering(PORT_ID, IP_ADDR, UDP_PORT) !=3D 0) { rte_exit(EXIT_FAILURE, "Flow rule creation failed\n"); } // // Cr=C3=A9er la r=C3=A8gle drop-all // if (create_drop_all_rule(PORT_ID) !=3D 0) { // rte_exit(EXIT_FAILURE, "Erreur cr=C3=A9ation r=C3=A8gle drop-all\n"); // } ret =3D rte_eth_dev_rx_intr_enable(PORT_ID, RX_ID); if (ret < 0) { rte_exit(EXIT_FAILURE, "Failed to enable RX interrupts\n"); } int intr_fd =3D rte_eth_dev_rx_intr_ctl_q_get_fd(PORT_ID, RX_ID); if (intr_fd < 0) { rte_exit(EXIT_FAILURE, "Failed to get interrupt fd\n"); } struct rte_epoll_event ev =3D { .epdata.event =3D EPOLLIN | EPOLLET, .fd =3D intr_fd }; ret =3D rte_epoll_ctl(RTE_EPOLL_PER_THREAD, EPOLL_CTL_ADD, intr_fd, &ev); if (ret < 0) { rte_exit(EXIT_FAILURE, "Failed to add fd to epoll\n"); } printf("Processing packets...\n"); struct rte_mbuf *bufs[MAX_PKT_BURST]; while (1) { uint16_t rx_count =3D rte_eth_rx_queue_count(PORT_ID, 0); printf("Paquets dans la RX queue 0: %u\n", rx_count); rx_count =3D rte_eth_rx_queue_count(PORT_ID, RX_ID); printf("Paquets dans la RX queue 5: %u\n", rx_count); // Wait for interrupt n =3D rte_epoll_wait(RTE_EPOLL_PER_THREAD, event, 1, 5000); // 5 secondes if (n < 0) { if (errno =3D=3D EINTR) { continue; } rte_exit(EXIT_FAILURE, "Epoll wait failed: %s\n", strerror(errno)); } // Clear any pending interrupts rte_eth_dev_rx_intr_disable(PORT_ID, RX_ID); // Process packets do { const uint16_t nb_rx =3D rte_eth_rx_burst(PORT_ID, RX_ID, bufs, MAX_PKT_BUR= ST ); if (nb_rx =3D=3D 0) break; printf("Received %u packet(s)\n", nb_rx); for (uint16_t i =3D 0; i < nb_rx; i++) { struct rte_ether_hdr *eth_hdr =3D rte_pktmbuf_mtod(bufs[i], struct rte_ether_hdr *); if (rte_be_to_cpu_16(eth_hdr->ether_type) =3D=3D RTE_ETHER_TYPE_IPV4) { struct rte_ipv4_hdr *ip_hdr =3D (struct rte_ipv4_hdr *)(eth_hdr + 1); char src_str[INET_ADDRSTRLEN]; char dst_str[INET_ADDRSTRLEN]; inet_ntop(AF_INET, &ip_hdr->src_addr, src_str, INET_ADDRSTRLEN); inet_ntop(AF_INET, &ip_hdr->dst_addr, dst_str, INET_ADDRSTRLEN); printf("Received IPv4 packet: %s -> %s, Size: %u bytes\n", src_str, dst_str, rte_pktmbuf_pkt_len(bufs[i])); } rte_pktmbuf_free(bufs[i]); } } while (1); clear_rx_queue(PORT_ID, 0); ret =3D rte_eth_dev_rx_intr_enable(PORT_ID, RX_ID); if (ret < 0) { rte_exit(EXIT_FAILURE, "Failed to re-enable RX interrupts\n"); } } rte_flow_flush(PORT_ID, &error); port_cleanup(PORT_ID); rte_eal_cleanup(); return 0; } Best regards, SidAli --0000000000006c9a54062e6a956d Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable

Dear DPDK Team,

I am using DPDK 23.11 with a= n X540-AT (ixgbe) NIC.

I am facing an issue where this card is not co= mpatible with a combination of two flow rules. To work around this, I attem= pted to create a single rule to redirect packets that match specific criter= ia to, let's say, queue 5. Initially, this works for a few packets, but= after that, no more packets are received.

I am unsure whether this i= ssue is related to the interrupts (though I=E2=80=99ve tested without inter= rupts and the problem persists) or not. I also thought that if queue 0 is f= ull (since the drop rule is not functioning), the filter might stop working= , so I tried clearing the queue to see if it would resolve the issue. Howev= er, even after that, the problem remains.

I am new to DPDK, so please= let me know if I am doing something wrong or if there are any suggestions = to address this issue.

Below is the code I have implemented:


<= div style=3D"color:rgb(204,204,204);background-color:rgb(31,31,31);font-fam= ily:"Droid Sans Mono","monospace",monospace;font-weight= :normal;font-size:14px;line-height:19px;white-space:pre">
#include "../include/fl= ow.h"
#include= "../include/port.h"
#include <stdio.h>=
#include = <string.h>

int flow_filtering(uint16_t port_id, uint32_t ip_addr, uint16_t udp_port) {
<= /span>struct rte_flow= _error error= ;
struct rte_flow_attr= attr =3D { .ingress =3D 1= , .priority = =3D 0 };
struct rte_flow_item pattern[4];
struct rte_flow_action<= /span> action[2];
= struct rte_fl= ow *flow;

// D=C3=A9finir le motif Ethernet
memset<= /span>(pattern, 0, sizeof= (pattern));<= /div>
pattern[0].type =3D RTE_FLOW_ITEM_TYPE_ETH;

// D=C3=A9= finir le motif IPv4
struct r= te_flow_item_ipv4 ipv4_spec =3D { .hdr.dst_addr =3D RTE_BE32(ip_addr) };
struct rte_flow_i= tem_ipv4 ipv4_mask =3D { .hdr.dst_addr =3D RTE_= BE32(0xFFFFFFFF) };
= pattern[1].type =3D RTE_FLOW_ITEM_TYPE_IPV4<= /span>;
pattern[1= ].spec =3D &ipv4_spe= c;
pattern[1].mask =3D= &ipv4_m= ask;

// D=C3=A9finir le motif UDP
struct= rte_flow_item_udp udp_spec =3D { .hdr.dst_port = =3D RTE_BE16(= udp_port) };
struct rte_flow_item_udp udp_mask =3D { .hdr.= dst_port =3D= RTE_BE16(0xFFFF) };
= pattern[= 2].type =3D RTE_FLOW_ITEM= _TYPE_UDP;
<= span style=3D"color:rgb(204,204,204)"> pattern[<= span style=3D"color:rgb(181,206,168)">2].spec =3D &udp_spec;
pattern[2].mask =3D &udp_mask;
// Terminer le motif
pat= tern[3].type =3D<= span style=3D"color:rgb(204,204,204)"> RTE_FLOW_ITEM_TYPE_END;

= // D=C3=A9finir l'action
action= [0].type =3D RTE_FLOW_ACTION_TYPE_QUEUE;
struct rte_flow_action_queue queue_action =3D { .index =3D R= X_ID };
action[0].conf =3D &= queue_action;
action[1].type =3D RTE_FLOW_ACTION_TYPE_END;
if (rte_flow_vali= date(port_id= , &attr,= pattern, ac= tion, &e= rror) !=3D <= /span>0) {
printf("=C3=89chec validation: %s\n", error.message);
<= span style=3D"color:rgb(204,204,204)"> return -1;
<= div> }
// Cr=C3= =A9er la r=C3=A8gle de flux
flow =3D rte_flow_create(port_id= , &attr<= span style=3D"color:rgb(204,204,204)">, pattern, action, &<= span style=3D"color:rgb(156,220,254)">error);
= if (flow =3D=3D NULL) {
= printf("Erreur lors de la cr=C3=A9ation de la r=C3=A8gle de flux : <= span style=3D"color:rgb(156,220,254)">%s\n", error.message);
= return -1;
= }

printf("R=C3= =A8gle de flux cr=C3=A9=C3=A9e avec succ=C3=A8s pour IP %u.%u.%u.%u et port UDP <= /span>%u\n",
(ip_addr >> 24) & 0xFF, (ip_addr >> 16) & = 0xFF,
(ip_addr >> 8= ) & 0xFF, ip_addr & 0xFF, udp_port);

retu= rn 0;=
}

int create_drop_all_ru= le(uint16_t <= /span>port_id) {
struct rte_flow_error error;
<= span style=3D"color:rgb(204,204,204)"> struct rte_flow_a= ttr attr =3D { .ingress =3D 1, .priority =3D 1 };
struct rte_flo= w_item pattern[4];
struct rte_flow_actio= n action[2];
struct rte_flow *flow;

= // D=C3=A9finir le motif Eth= ernet
memset(pattern, 0, sizeof(pattern)= );
pattern[0].type =3D RTE_FLOW_ITEM_TYPE_ETH;

// D=C3=A9fini= r le motif IPv4
= struct rte_flow_item_ipv4 ipv4_spec;
struct rte_flow_item= _ipv4 ipv4_mask;
= pattern[= 1].type =3D RTE_FLOW_ITEM_TYPE_IPV4;
pa= ttern[1].spec =3D= &ipv4_spec;
pattern[1].mask =3D &ipv4_mask;

// D=C3=A9= finir le motif UDP
= struct rte_flow_item_udp udp_spec;
<= span style=3D"color:rgb(204,204,204)"> struct rte_flow_i= tem_udp udp_mask;
= pattern[= 2].type =3D RTE_FLOW_ITEM_TYPE_UDP;
pat= tern[2].spec =3D<= span style=3D"color:rgb(204,204,204)"> &udp_spec;
pattern[2].ma= sk =3D &udp_mask;

// Terminer le= motif
<= span style=3D"color:rgb(156,220,254)">pattern[3].type =3D RTE_FLOW_ITEM_TYPE_END;

// D=C3=A9fi= nir l'action
= action[0].type = =3D RTE_FLOW_ACTION_TYPE_DROP;
stru= ct rte_flow_action_queue queu= e_action; // temporary<= /div>
action[0].conf =3D &queue_action;
action[1].type =3D RTE_FLOW_ACTION_TYPE_END;

// Validation & Cr=C3=A9ation
= if (rte_flow_validate(port_id, &attr, pattern, action, &error) !=3D= 0) {
<= div> printf(= "=C3=89chec validation: = %s\n", error.message);
return -1;
}

= flow =3D = rte_flow_create(port_id, &attr, pattern, action, &error);
if (flow =3D=3D NULL) {
printf("=C3=89chec cr=C3=A9ation: %s\n", error.message);
= return -1;
}

<= /span>printf("= R=C3=A8gle DROP cr=C3=A9=C3=A9e.\n");
return= 0;
}


#include "../include/port.h"
= #include <stdio.h= >
#include <rte_arp.h>

// Configuration par d=C3=A9faut du port
static struct rte_eth_conf port_conf =3D {
.txmo= de =3D {
.mq_mode =3D RTE_ETH_MQ_TX_NONE,=
},
<= span style=3D"color:rgb(204,204,204)"> .rxmode <= span style=3D"color:rgb(212,212,212)">=3D {
= .offloads =3D RTE_ETH_RX_OFFLOAD_UDP_CKSUM | RTE_ETH_RX_OFFLOAD_IPV4_CKSUM,
= .mq_mode = =3D RTE_ETH_MQ_RX_NONE,
= .max_lro_pkt_size =3D 9000,
},<= /div>
.intr_conf =3D {
.rxq =3D 1,
}
};

= int port_init= (uint16_t port_id, struct<= span style=3D"color:rgb(204,204,204)"> rte_mempool <= span style=3D"color:rgb(212,212,212)">*mbuf_pool) {=
int <= /span>retval;
struct rte_eth_dev_info dev_info;
= struct rte_e= th_rxconf rxq_conf;
struct rte_eth_txcon= f txq_conf;<= /span>

// Obtenir les informations sur le p=C3= =A9riph=C3=A9rique
= retval = =3D rte_eth_dev_info_get(port_id, &dev_info);

if (retval !=3D 0) {
return retval;
}

if (NUM_RX > dev_info.max_rx_queues) {
pri= ntf("Erreur: NUM_RX d=C3=A9passe le maximum support= =C3=A9 (%u)= \n", de= v_info.max_rx_queues);
= return -1;
= }

<= span style=3D"color:rgb(106,153,85)">// Configurer le p=C3=A9riph=C3=A9riqu= e Ethernet
retval =3D rte_eth_dev_configure(port_id, NUM_RX, NUM_TX, &port_conf);
if (retval !=3D 0) {
<= /span>return retval= ;
}

// Con= figurer les queues RX
rxq_conf =3D dev_info.default_rxconf;
rxq_co= nf.offloads = =3D port_con= f.rxmode.offloads;
for(int i =3D 0; i < NUM_RX; i++){
retval =3D rte_eth_rx_queue_setup(port_id, i, 128, <= /span>rte_eth_dev_socket_id(port_id), &rxq_conf, = mbuf_pool);
if (retval < 0) {
= return = retval;
}

}

// Co= nfigurer les queues TX
txq_conf =3D dev_info.default_txconf= ;
txq= _conf.offloads =3D port_= conf.txmode.= offloads;
retval =3D rte_eth_tx_queue_setup(port_id= , TX_ID, 128, rte_eth_dev= _socket_id(port_id), &txq_conf);
if (retval = < 0) {
return retval;
}

// D=C3=A9marrer l= e p=C3=A9riph=C3=A9rique Ethernet
retval =3D rte_eth_dev_start(port_= id);
if (retval < = 0) {
return retval;
}=

// Activer le mode promiscuous (facultat= if)
// rte_eth_promiscuous_enable(port_id);

printf("Port %u initialis=C3=A9 avec succ=C3=A8s\n", port_id);
return 0;
}

void port_cleanup(<= /span>uint16_t port_= id) {
rte_eth_dev_stop(port_id);
rte_eth_dev_close(port_id);
printf("Port %u arr=C3=AAt=C3=A9 et nettoy=C3=A9\n", port_id);
}


void send_gratuitous_a= rp(uint16_t <= /span>port_id,
struct rte_mempool *mbuf_pool,
const = struct rte_ether_addr= *local_mac<= /span>,
uint32_t local_ip)
{
struct = rte_mbuf *mbuf =3D= rte_pktmbuf_alloc(= mbuf_pool);
= if (!mbuf) {
fprintf(stderr, "Failed to allocate mbuf\n");
<= span style=3D"color:rgb(204,204,204)"> return;
}

<= div> const uint16_t pkt_size =3D sizeof(struct rte_ether_hdr) = + sizeof(struct rte_arp_hdr);
const uint16_t min_frame_size =3D 60; // Minimum Ethernet frame size without FCS
<= span style=3D"color:rgb(204,204,204)"> uint16_t <= span style=3D"color:rgb(156,220,254)">padding =3D (pkt_size < min_frame_size) ? (min_frame_size - pkt_size) = : 0;

char *pkt_data= =3D rte_pktmbuf_append(mbuf, pkt_size + padding= );
if (!pkt_data) {
fprin= tf(stderr, "Failed to append data in = mbuf\n"= );
<= span style=3D"color:rgb(220,220,170)">rte_pktmbuf_free(mbu= f);
return;
}

// Zero out padding space
if (padding <= span style=3D"color:rgb(212,212,212)">> 0) {
mems= et(pkt_data = + pkt_size, 0, padding);
= }

// Ethernet Header
= struct rte_ether_hdr *= eth_hdr =3D<= span style=3D"color:rgb(204,204,204)"> (struct rte_ether_hdr *)pkt_data;
rte_ether_addr_copy(local_mac, &eth_hdr= ->src_addr);
memset(&eth_hdr->dst_addr, 0xFF, RTE_ETHER_ADDR_LEN); // Broa= dcast MAC
eth_hdr->ether= _type =3D rte_cpu_to_be_16(RTE_ETHER_TYPE_ARP);<= /div>
// ARP Header
stru= ct rte_arp_hdr *arp_hdr <= /span>=3D (struct rte_arp_hdr *)(pkt_data + sizeof(struct rte_ether_hdr));
arp_hdr= ->arp_hardware =3D rte_cpu_to_be_16(RTE_ARP_HRD_ETH= ER);
arp_hdr->arp_protocol =3D rte_cpu_to_be_16(<= /span>RTE_ETHER_TYPE_IPV4);
arp_hdr= ->arp_hlen =3D RTE_ETH= ER_ADDR_LEN;
arp_hdr->arp_plen =3D 4;
arp_hdr-= >arp_opcode =3D rte_cpu_to_be_16(RTE_ARP_OP_REQUEST<= /span>); // Correcting this to request

// Sender MAC/IP
rte_ether_addr_copy= (local_mac, = &arp_hdr= ->arp_data.arp_sha);
= arp_hdr->arp_data.arp_si= p =3D rte_cpu_to_be_32(= local_ip);

// Target MAC/IP (ARP request with the same IP as source)
memset(&arp_hdr->arp_data<= span style=3D"color:rgb(204,204,204)">.arp_tha, 0, RTE_ETHER_ADDR_LEN); // Unknown target MAC
arp_h= dr->arp_data.arp_tip = =3D rte_cpu_to_be_32(local_ip); // Target IP =3D Our own IP

// T= ransmit
= struct rte_mbuf *tx_pkts[1];
tx_pkts[0] =3D mbuf;
= uint16_t = nb_tx =3D rte_eth_tx_burst(port_id, TX_ID, tx_pkts, 1);

if (nb= _tx < 1) {
= rte_pktmbuf_free(mbuf);
<= div> printf(= "Failed to send Gratuito= us ARP\n");
} <= span style=3D"color:rgb(197,134,192)">else {
= printf(= "Gratuitous ARP sent successfully\n");
}
}


#include "../include/flow.h"
#include <= span style=3D"color:rgb(206,145,120)">"../include/port.h"<= /div>
#include &= lt;unistd.h>
#in= clude <rte_eal.h>
#include = <rte_mbuf.h>
#include <= rte_ethdev.h>
#i= nclude <rte_ether.h>
#include <rte_ip.h>
#include &= lt;arpa/inet.h>
= #include <sys/epoll.h>

#define MAX_PKT_BURST 32
#define IP_ADDR RTE_IPV4(10, 81, = 16, 111)
#define UDP_PORT 1234

vo= id clear_rx_queue(uint16_t port_id, uint16_t rx_id) {
struct rte_mbuf *bufs[MAX_PKT_BURST];
uint16_t nb_rx= ;


while ((nb_rx =3D= rte_eth_rx_burst(port_id, rx_id, bufs, MAX_PKT_BURST)) > 0) {
=
<= span style=3D"color:rgb(197,134,192)">for (uint16_t<= span style=3D"color:rgb(204,204,204)"> i =3D 0; i < nb_rx; i++) {
<= div> rte_pktmbuf_free(bufs[i]);
}
}
}

int main(int argc, = char **argv<= /span>) {
struct rte_mempool *mbuf_pool;
struct rte_ether_ad= dr local_mac= ;
struct rte_epoll_event event[1];
struct rte_flow_er= ror error;
int ret, n;

// Initialize EAL
ret = =3D rte_eal_init(argc, argv);
if (ret < = 0) {
rte_exit(EXIT_FAILURE, "EA= L initialization failed\n");
}

// Create mbuf pool
=
mbuf_pool = =3D rte_pktm= buf_pool_create("MBUF_POOL", NUM= _MBUFS, MBUF_CACHE_SIZE, 0,
RTE_MBUF_DEFAULT_BUF_SIZE, rte_sock= et_id());
if (mbuf_pool =3D=3D NULL) {
<= div> rte_exit(EXIT_FAILURE, "Cannot create mbuf pool\n");
}

// Initialize port
if (port_init(= PORT_ID, mbuf_pool) !=3D 0) {
rte_exit(EXIT_FAILURE, "= ;Port initialization failed\n= ");
}

= // Get MAC address
ret =3D rte_eth_mac= addr_get(PORT_ID, &local_mac);
if(ret !=3D 0) {
rte_exit(EXIT_FAI= LURE, "Failed to get MAC address\n&q= uot;);
}

= send_gratuitous_arp(PORT_ID, mbuf_pool, &local_mac= , IP_ADDR);


<= span style=3D"color:rgb(197,134,192)">if (flow_filtering(PORT_ID, IP_ADDR, UDP_PORT) !=3D = 0) {
= rte_exit(= EXIT_FAILURE, "Flow rule creation failed\n");
}

// // Cr=C3=A9er la r=C3=A8gle drop-all
// if (create_drop_all_rule(PORT_ID) !=3D 0) {
// rte_exit(EXIT_FAILURE, "Erreur cr=C3=A9ation r=C3=A8gle dro= p-all\n");
= // }

ret =3D rte_eth_dev_rx_intr_en= able(PORT_ID,= RX_ID);
if (ret < 0) {
rte_exit(EXIT_FAI= LURE, "Failed to enable RX interrupts\n");
= }

int intr_fd =3D rte_= eth_dev_rx_intr_ctl_q_get_fd(= PORT_ID, RX_ID= );
if= (intr_fd < 0) {
rte_e= xit(EXIT_FAILURE, "Failed to get inte= rrupt fd\n");
}

struct rte_epoll_event<= span style=3D"color:rgb(204,204,204)"> ev =3D {
.epdata.event =3D EPOLLIN | EPOLLET,
= .fd = =3D intr_fd<= /div>
};

ret =3D rte_epoll_ctl(RTE_EPOLL_PER_THREAD, EPOLL_CTL_ADD, intr_fd, &ev);
if (<= span style=3D"color:rgb(156,220,254)">ret < 0) {
<= span style=3D"color:rgb(204,204,204)"> rte_exit(EXIT_FAILURE, &q= uot;Failed to add fd to epoll= \n");
}

= printf(= "Processing packets...\n= ");
struct rte_mbuf *bufs[MAX_PKT_BURST];

<= /span>while (1) {
uint16_t <= span style=3D"color:rgb(156,220,254)">rx_count =3D<= span style=3D"color:rgb(204,204,204)"> rte_eth_rx_queue_count(PORT_ID, 0);
printf("Paquets dans la RX queue 0: %u\n"<= span style=3D"color:rgb(204,204,204)">, rx_count);<= /div>
rx_count =3D rte_eth_rx_queue_count(PORT_ID, RX_ID);
printf("Paquets dans la RX queue 5: %u\n", rx_count);
// Wait for interrupt
n =3D rte_epoll_wait(RTE_EPOLL_PER_THREAD, event, 1, 5000); // 5 secondes

if (n < 0) {
if (<= span style=3D"color:rgb(86,156,214)">errno =3D=3D EINTR) {
=
continue;
= }
= rte_exit(EXIT= _FAILURE, "Epoll wait failed: %s\n<= /span>", strer= ror(errno));<= /span>
}
// Clear any pending interrupts
rte_eth_dev_rx_intr_disable(PORT_ID, RX_ID);=

// Process packets
do {
<= div>
const uint16_t nb_rx =3D rte_eth_rx_burst(PORT_I= D, RX_ID, bufs, MAX_PKT_BU= RST);
if (nb_rx =3D=3D 0) break;


= printf("Received %u packet(s)\n", nb_rx);
for (uint16_t i =3D = 0; i<= span style=3D"color:rgb(204,204,204)"> < nb_rx; i++) {
= struct rte_e= ther_hdr *= eth_hdr =3D = rte_pktmbuf_mtod(bufs[i= ], struct rte_ether_hdr *);
if (rte_be_to_cpu_16(eth_hdr->ether_type) =3D=3D RTE_ETHER_TYPE_IPV4) {
= struct rte_ipv4_hdr *ip_hdr =3D (struct r= te_ipv4_hdr *)(eth_hdr = + 1);=
char src_str[INET_ADDRSTRLEN];<= /span>
= char dst_str= [INET_ADDRSTRLEN];
=
= inet_ntop(AF_INET, &ip_hdr->src_addr, src_str, INET_ADDRSTRLEN)= ;
= inet_ntop(= AF_INET, &ip_hdr->dst_addr, dst_str, INET_ADDRSTRLEN);
<= /span>
= printf(&quo= t;Received IPv4 packet: %s -> %s, Size= : %u bytes\n= ",
src_str, dst_str, rte_pktmbuf_pkt_len<= /span>(bufs[= i]));
= }
=
= rte_pktmbuf_free(bufs[i]);
= }
} <= /span>while (1);
clear_= rx_queue(PORT_ID, 0);

ret =3D rte_eth_dev_rx_intr_enable(PORT_ID, RX_ID);
if (ret < 0) {
<= /span>rte_exit(EXIT_= FAILURE, "Failed to re-enable RX interrupts<= span style=3D"color:rgb(215,186,125)">\n");
}
<= span style=3D"color:rgb(204,204,204)"> }

rte_flow_flush(PORT_ID, &<= span style=3D"color:rgb(156,220,254)">error);
= port_cleanup(PORT_ID);
= rte_eal_cleanup= ();
return 0;
}

Bes= t regards,
SidAli
--0000000000006c9a54062e6a956d--