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 1FED545C85 for ; Tue, 5 Nov 2024 09:23:29 +0100 (CET) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id DCD3B4025D; Tue, 5 Nov 2024 09:23:28 +0100 (CET) Received: from sender4-of-o54.zoho.com (sender4-of-o54.zoho.com [136.143.188.54]) by mails.dpdk.org (Postfix) with ESMTP id 75DF9400EF for ; Tue, 5 Nov 2024 09:23:27 +0100 (CET) ARC-Seal: i=1; a=rsa-sha256; t=1730795006; cv=none; d=zohomail.com; s=zohoarc; b=khcgA4Zdxtm90l+amTQAnGpVus88qea2bdfcwSOENwAxX6VAHmpUPoyNf+deB6A9fVdOeNy3Abk8gOK8AuXCppJs2AnbB/nHYHcpHZ8Snkw10RnYEG1yr4HWYp3eEGrkXAzxnwR2GvLec42dyzNo+TfVvEE9LJHl1hPJb24O+XE= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1730795006; h=Content-Type:Date:Date:From:From:MIME-Version:Message-ID:Subject:Subject:To:To:Message-Id:Reply-To:Cc; bh=bDM99HvZArNk8EXk8HLAnPx7CN9UszFYC5gwIV0MOzg=; b=Koan2YVxoSkCGwPwMGMrHD5QSIq8nfouGMSYwk4xyNxXBStczgRHYSIdQIPHsGyHr5pna846CLwgUnBqdMnU1OLkO/qjC2OVzvy5vQ/6z2IDdjJhqhNnomUjPCrRjaRa1mm/iAHLKgxDxoeH3EEn2ZlYt++bWgmhbblmtUjqNjY= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass header.i=zohomail.com; spf=pass smtp.mailfrom=gopinath.gk@zohomail.com; dmarc=pass header.from= DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; t=1730795006; s=zm2022; d=zohomail.com; i=gopinath.gk@zohomail.com; h=Date:Date:From:From:To:To:Message-Id:Message-Id:In-Reply-To:Subject:Subject:MIME-Version:Content-Type:Reply-To:Cc; bh=bDM99HvZArNk8EXk8HLAnPx7CN9UszFYC5gwIV0MOzg=; b=b8LVBhGRiRm/H902L3zcGnLAF+biD4xkj+WmxAGpj6R5nJ/BoT4Zr5ihgCU+mpA7 L+SYVsN/xsdYRxW/YrC9ub/UYNsjQ5QfElrIE+eA7Woad45QidpjKYPqpbFHSw1p0sJ PWFqBcE7nazCwv+/en0rVQsv69Nx+nWzlieAvL+Q= Received: from mail.zoho.com by mx.zohomail.com with SMTP id 1730795004398683.4387218422985; Tue, 5 Nov 2024 00:23:24 -0800 (PST) Date: Tue, 05 Nov 2024 13:53:24 +0530 From: Gopinath K To: "users" Message-Id: <192fb6be188.1149bb382642049.7819154315379406165@zohomail.com> In-Reply-To: Subject: Error with SEND_TO_KERNEL Action during Flow creation on Mellanox CX-5 MIME-Version: 1.0 Content-Type: multipart/alternative; boundary="----=_Part_2023389_597917094.1730795004297" Importance: Medium User-Agent: Zoho Mail X-Mailer: Zoho Mail 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 ------=_Part_2023389_597917094.1730795004297 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable Hi, =C2=A0 =C2=A0 =C2=A0I'm new to DPDK, and have been working on creating flow= rules by using DPDK, to steer traffic to the kernel. =C2=A0 =C2=A0 =C2=A0To understand the functionality of the Mellanox Bifurac= ted drive, i attempted to steer ICMP packets to Linux Kernel and other traf= fics to DPDK application. first i tried to create simple flow rule which dr= ops the packet whose destination equals 192.168.3.2=C2=A0https://doc.dpdk.o= rg/guides/howto/rte_flow.html=C2=A0the flow created successfully without an= error. =C2=A0 =C2=A0 =C2=A0However the issue arises when I attempt to use the RTE_= FLOW_ACTION_TYPE_SEND_TO_KERNEL, which results in an error. Below the sample code. =C2=A0 =C2=A0 =C2=A01. functions to validate and create flow rule. static ::rte_flow* create_flow(uint16_t port_id, rte_flow_attr& attr, rte_f= low_item& pattern, rte_flow_action& actions) { =C2=A0=C2=A0=C2=A0 rte_flow_error error; =C2=A0=C2=A0=C2=A0 auto flow =3D rte_flow_create(port_id, &attr, &pattern, = &actions, &error); =C2=A0=C2=A0=C2=A0 if (!flow) { =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 printf("[create flow rule] faile= d to create flow rule, error: %s.\n", error.message); =C2=A0=C2=A0=C2=A0 } =C2=A0=C2=A0=C2=A0 return flow; } bool validate_flow(uint16_t port_id, rte_flow_attr& attr, rte_flow_item& pa= ttern, rte_flow_action& action) { =C2=A0=C2=A0=C2=A0 rte_flow_error error; =C2=A0=C2=A0=C2=A0 auto res =3D rte_flow_validate(port_id, &attr, &pattern,= &action, &error); =C2=A0=C2=A0=C2=A0 if (res < 0) { =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 printf("[validate flow rule] val= idate flow failed, error: %s\n", error.message); =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 return false; =C2=A0=C2=A0=C2=A0 } =C2=A0=C2=A0=C2=A0 return true; } =C2=A0 =C2=A0 =C2=A02. function to enable isolated mode on network port. bool enable_isolated_mode(uint16_t port_id) { =C2=A0=C2=A0=C2=A0 rte_flow_error error; =C2=A0=C2=A0=C2=A0 // enable isolated mode. =C2=A0=C2=A0=C2=A0 if (rte_flow_isolate(port_id, 1, &error) < 0) { =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 printf("[isolated mode] failed t= o enable isolated mode on port %u, error: %s\n", port_id, error.message); =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 return false; =C2=A0=C2=A0=C2=A0 } =C2=A0=C2=A0=C2=A0 printf("[isolated mode] isolated mode enabled on port %u= \n", port_id); =C2=A0=C2=A0=C2=A0 return true; } =C2=A0 =C2=A0 =C2=A03. port initialization function. static inline int port_initilization(uint16_t port, rte_mempool *mbuf_pool) { =C2=A0=C2=A0=C2=A0 rte_eth_conf port_conf; =C2=A0=C2=A0=C2=A0 if (!rte_eth_dev_is_valid_port(port)) { =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0printf("[port i= nit] port %u is not a valid port\n", port); =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0return -1; =C2=A0=C2=A0=C2=A0 } =C2=A0=C2=A0=C2=A0 if (!enable_isolated_mode(port)) { =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 return -1; =C2=A0=C2=A0=C2=A0 } =C2=A0=C2=A0=C2=A0 memset(&port_conf, 0, sizeof(rte_eth_conf)); =C2=A0=C2=A0=C2=A0 rte_eth_dev_info device_info; =C2=A0=C2=A0=C2=A0 auto retval =3D rte_eth_dev_info_get(port, &device_info)= ; =C2=A0=C2=A0=C2=A0 if (retval !=3D 0) { =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0printf("[pirt i= nit] getting device(port %u) info, error: %d [%s]\n", port, rte_errno, ::rt= e_strerror(rte_errno)); =C2=A0=C2=A0=C2=A0 =09return retval; =C2=A0=C2=A0=C2=A0 } =C2=A0=C2=A0=C2=A0 if (device_info.tx_offload_capa & RTE_ETH_TX_OFFLOAD_MBU= F_FAST_FREE) =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0port_conf.txmod= e.offloads |=3D RTE_ETH_TX_OFFLOAD_MBUF_FAST_FREE; =C2=A0=C2=A0=C2=A0 uint16_t rx_rings =3D 1; =C2=A0=C2=A0=C2=A0 uint16_t tx_rings =3D 1; =C2=A0=C2=A0=C2=A0 retval =3D rte_eth_dev_configure(port, rx_rings, tx_ring= s, &port_conf); =C2=A0=C2=A0=C2=A0 if (retval !=3D 0) { =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0printf("[port i= nit] failed to configure port(%u), error: %d [%s]\n", port, rte_errno, ::rt= e_strerror(rte_errno)); =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0return retval; =C2=A0=C2=A0=C2=A0 } =C2=A0=C2=A0=C2=A0 uint16_t nb_rxd =3D RX_RING_SIZE; =C2=A0=C2=A0=C2=A0 uint16_t nb_txd =3D TX_RING_SIZE; =C2=A0=C2=A0=C2=A0 retval =3D rte_eth_dev_adjust_nb_rx_tx_desc(port, &nb_rx= d, &nb_txd); =C2=A0=C2=A0=C2=A0 if (retval !=3D 0) { =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0printf("[port i= nit] rte_eth_dev_adjust failed, error: %d [%s]\n", rte_errno, ::rte_strerro= r(rte_errno)); =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0return retval; =C2=A0=C2=A0=C2=A0 } =C2=A0=C2=A0=C2=A0 for (auto q =3D 0; q < rx_rings; q++) { =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0retval =3D rte_= eth_rx_queue_setup(port, q, nb_rxd, rte_eth_dev_socket_id(port), NULL, mbuf= _pool); =C2=A0 =C2=A0 if (retval < 0) =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0return retval; =C2=A0=C2=A0=C2=A0 } =C2=A0=C2=A0=C2=A0 auto tx_conf =3D device_info.default_txconf; =C2=A0=C2=A0=C2=A0 tx_conf.offloads =3D port_conf.txmode.offloads; =C2=A0=C2=A0=C2=A0 for (auto q =3D 0; q < tx_rings; q++) { =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 retval =3D rte_eth_tx_queue_setu= p(port, q, nb_txd, rte_eth_dev_socket_id(port), &tx_conf); =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 if (retval < 0) =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 return r= etval; =C2=A0=C2=A0=C2=A0 } =C2=A0=C2=A0=C2=A0 ::rte_ether_addr addr; =C2=A0=C2=A0=C2=A0 retval =3D rte_eth_macaddr_get(port, &addr); =C2=A0=C2=A0=C2=A0 if (retval !=3D 0) =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 return retval; =C2=A0=C2=A0=C2=A0 retval =3D rte_eth_dev_start(port); =C2=A0=C2=A0=C2=A0 if (retval !=3D 0) { =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 printf("[port init] starting por= t %u failed, error: %d [%s]\n", port, rte_errno, rte_strerror(rte_errno)); =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 return retval; =C2=A0=C2=A0=C2=A0 } =C2=A0=C2=A0=C2=A0 printf("[port init] successfully started port: %u\n", po= rt); =C2=A0=C2=A0=C2=A0 printf("port %u MAC: %02" PRIx8 " %02" PRIx8 " %02" PRIx= 8 " %02" PRIx8 " %02" PRIx8 " %02" PRIx8 "\n", port, RTE_ETHER_ADDR_BYTES(&= addr)); =C2=A0=C2=A0=C2=A0 init_ingress_flow_rules(port); =C2=A0=C2=A0=C2=A0 init_egress_flow_rule(port); =C2=A0=C2=A0 return 0; } =C2=A0 =C2=A0 =C2=A04. Flow rule static void init_ingress_flow_rule(uint32_t port_id) { =C2=A0=C2=A0=C2=A0 rte_flow_attr attr =3D {0}; =C2=A0=C2=A0=C2=A0 rte_flow_item pattern[4]; =C2=A0=C2=A0=C2=A0 rte_flow_action action[2]; =C2=A0=C2=A0=C2=A0 attr.ingress =3D 1; =C2=A0=C2=A0=C2=A0 memset(pattern, 0, sizeof pattern); =C2=A0=C2=A0=C2=A0 rte_flow_item_eth eth_spec; =C2=A0=C2=A0=C2=A0 rte_flow_item_eth eth_mask; =C2=A0=C2=A0=C2=A0 memset(ð_spec, 0, sizeof eth_spec); =C2=A0=C2=A0=C2=A0 memset(ð_mask, 0, sizeof eth_mask); =C2=A0=C2=A0=C2=A0 pattern[0].type =3D RTE_FLOW_ITEM_TYPE_ETH; =C2=A0=C2=A0=C2=A0 pattern[0].spec =3D ð_spec; =C2=A0=C2=A0=C2=A0 rte_flow_item_ipv4 ipv4_spec; =C2=A0=C2=A0=C2=A0 rte_flow_item_ipv4 ipv4_mask; =C2=A0=C2=A0=C2=A0 memset(&ipv4_spec, 0, sizeof ipv4_spec); =C2=A0=C2=A0=C2=A0 memset(&ipv4_mask, 0, sizeof ipv4_mask); =C2=A0=C2=A0=C2=A0 pattern[1].type =3D RTE_FLOW_ITEM_TYPE_IPV4; =C2=A0=C2=A0=C2=A0 pattern[1].spec =3D &ipv4_spec; =C2=A0=C2=A0=C2=A0 pattern[1].mask =3D &ipv4_mask; =C2=A0=C2=A0=C2=A0 rte_flow_item_icmp icmp_spec; =C2=A0=C2=A0=C2=A0 rte_flow_item_icmp icmp_mask; =C2=A0=C2=A0=C2=A0 memset(&icmp_spec, 0, sizeof icmp_spec); =C2=A0=C2=A0=C2=A0 memset(&icmp_mask, 0, sizeof icmp_mask); =C2=A0=C2=A0=C2=A0 icmp_spec.hdr.icmp_type =3D 0; =C2=A0=C2=A0=C2=A0 pattern[2].type =3D RTE_FLOW_ITEM_TYPE_ICMP; =C2=A0=C2=A0=C2=A0 pattern[2].spec =3D &icmp_spec; =C2=A0=C2=A0=C2=A0 pattern[2].mask =3D &icmp_mask; =C2=A0=C2=A0=C2=A0 pattern[3].type =3D RTE_FLOW_ITEM_TYPE_END; =C2=A0=C2=A0=C2=A0 action[0].type =3D RTE_FLOW_ACTION_TYPE_SEND_TO_KERNEL; =C2=A0=C2=A0=C2=A0 action[1].type =3D RTE_FLOW_ACTION_TYPE_END; =C2=A0=C2=A0=C2=A0 if (validate_flow(port_id, attr, pattern[0], action[0]))= { =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 printf("[init flow rule] validat= ed successfully.\n"); =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 auto flow =3D create_flow(port_i= d, attr, pattern[0], action[0]); =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 if (flow !=3D NULL) { =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 printf("= [rte flow rule] successfully created a egress flow rule in port %u\n", port= _id); =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 } =C2=A0=C2=A0=C2=A0 } } When I try to run the above program, the flow rule validated successfully w= ith `rte_flow_validate()`, but failed on creating the flow with an error of= `hardware refuses to create flow`. [init flow rule] validated successfully. [create flow rule] failed to create flow rule, error: hardware refuses to c= reate flow. The same error arise when try to create the flow in `dpdk-testpmd` program. testpmd> flow isolate 0 true testpmd> port start 0 testpmd> flow create 0 ingress pattern eth / ipv4 / icmp / end actions send= _to_kernel / end port_flow_complain(): Caught PMD error type 1 (cause unspecified): hardware= refuses to create flow: Operation not supported Can anyone tell me whether my code is correct or not? Can anyone tell me whether my code is correct or not? and any idea how to u= se SEND_TO_KERNEL Action on Mellanox CX-5 NIC's. System specification. =C2=A0 =C2=A0 =C2=A0Operating System: Debian =C2=A0 =C2=A0 =C2=A0OS Version: 12.7 =C2=A0 =C2=A0 =C2=A0DPDK version: 24.07 Thanks and Regards, Gopinath. Sent using ------=_Part_2023389_597917094.1730795004297 Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable =
Hi,

     I'm ne= w to DPDK, and have been working on creating flow rules by using DPDK, to s= teer traffic to the kernel.

     To understand the fu= nctionality of the Mellanox Bifuracted drive, i attempted to steer ICMP pac= kets to Linux Kernel and other traffics to DPDK application. first i tried = to create simple flow rule which drops the packet whose destination equals = 192.168.3.2 (refrenced from from API examples) the flow created successfully without an error.

=
     However the issue arises when I attempt to use the= RTE_FLOW_ACTION_TYPE_SEND_TO_KERNEL, which results in an error.
<= div>

     2. function to enable isolated mode on network p= ort.
bool enable_is= olated_mode(uint16_t port_id) {
    rte_flow_e= rror error;

    // enable isola= ted mode.
    if (rte_flow_isolate(port_id, 1,= &error) < 0) {
      &n= bsp; printf("[isolated mode] failed to enable isolated mode on port %u, err= or: %s\n", port_id, error.message);
    &= nbsp;   return false;
    }

    printf("[isolated mode] isolated mo= de enabled on port %u\n", port_id);
    return= true;
}

     3. port initialization function.
static inline int
port_initiliz= ation(uint16_t port, rte_mempool *mbuf_pool) {
  &n= bsp; rte_eth_conf port_conf;

   = ; if (!rte_eth_dev_is_valid_port(port)) {
   &= nbsp;      printf("[port init] port %u is not= a valid port\n", port);
      =     return -1;
    }
    if (!enable_isolated_mode(port)) {
        return -1;
 = ;   }
    memset(&port_conf, 0, = sizeof(rte_eth_conf));
    rte_eth_dev_info de= vice_info;
    auto retval =3D rte_eth_dev_inf= o_get(port, &device_info);
    if (retval = !=3D 0) {
        &nb= sp; printf("[pirt init] getting device(port %u) info, error: %d [%s]\n= ", port, rte_errno, ::rte_strerror(rte_errno));
  &= nbsp; =09return retval;
    }
    if (device_info.tx_offload_capa & RTE_E= TH_TX_OFFLOAD_MBUF_FAST_FREE)
     &= nbsp;    port_conf.txmode.offloads |=3D RTE_ETH_TX_OFFL= OAD_MBUF_FAST_FREE;

    uint16_= t rx_rings =3D 1;
    uint16_t tx_rings =3D 1;=
    retval =3D rte_eth_dev_configure(port, rx= _rings, tx_rings, &port_conf);
    if (ret= val !=3D 0) {
        = ;  printf("[port init] failed to configure port(%u), error: %d [%= s]\n", port, rte_errno, ::rte_strerror(rte_errno));
 &nb= sp;        return retval;
=
    }

    u= int16_t nb_rxd =3D RX_RING_SIZE;
    uint16_t = nb_txd =3D TX_RING_SIZE;
    retval =3D rte_et= h_dev_adjust_nb_rx_tx_desc(port, &nb_rxd, &nb_txd);
&= nbsp;   if (retval !=3D 0) {
   &nbs= p;      printf("[port init] rte_eth_dev_adjus= t failed, error: %d [%s]\n", rte_errno, ::rte_strerror(rte_errno));
          return r= etval;
    }

&nbs= p;   for (auto q =3D 0; q < rx_rings; q++) {
&nb= sp;         retval =3D rte_eth= _rx_queue_setup(port, q, nb_rxd, rte_eth_dev_socket_id(port), NULL, mbuf_po= ol);
    if (retval < 0)
 &nb= sp;       return retval;
 =    }

    auto tx_conf= =3D device_info.default_txconf;
    tx_conf.o= ffloads =3D port_conf.txmode.offloads;
    for= (auto q =3D 0; q < tx_rings; q++) {
   &nb= sp;    retval =3D rte_eth_tx_queue_setup(port, q, nb_txd, rt= e_eth_dev_socket_id(port), &tx_conf);
   &= nbsp;    if (retval < 0)
   =          return retval;
    }

    ::r= te_ether_addr addr;
    retval =3D rte_eth_mac= addr_get(port, &addr);
    if (retval !=3D= 0)
        return retval;=

    retval =3D rte_eth_dev_sta= rt(port);
    if (retval !=3D 0) {
        printf("[port init] starting = port %u failed, error: %d [%s]\n", port, rte_errno, rte_strerror(rte_errno)= );

    rte_flow_item_ipv4 ipv4_mask;
    memset(&ipv4_spec, 0, sizeof ipv4_spec);
    memset(&ipv4_mask, 0, sizeof ipv4_mask);=
    pattern[1].type =3D RTE_FLOW_ITEM_TYPE_IP= V4;
    pattern[1].spec =3D &ipv4_spec;
    pattern[1].mask =3D &ipv4_mask;

    rte_flow_item_icmp icmp_spec;
    rte_flow_item_icmp icmp_mask;
&nb= sp;   memset(&icmp_spec, 0, sizeof icmp_spec);
=     memset(&icmp_mask, 0, sizeof icmp_mask);
    icmp_spec.hdr.icmp_type =3D 0;
 &n= bsp;  pattern[2].type =3D RTE_FLOW_ITEM_TYPE_ICMP;
 = ;   pattern[2].spec =3D &icmp_spec;
  = ;  pattern[2].mask =3D &icmp_mask;
   = ; pattern[3].type =3D RTE_FLOW_ITEM_TYPE_END;

=     action[0].type =3D RTE_FLOW_ACTION_TYPE_SEND_TO_KERNEL;<= br>
    action[1].type =3D RTE_FLOW_ACTION_TYPE_EN= D;

    if (validate_flow(port_i= d, attr, pattern[0], action[0])) {
    &n= bsp;   printf("[init flow rule] validated successfully.\n");
<= /div>
        auto flow =3D create_f= low(port_id, attr, pattern[0], action[0]);
   =      if (flow !=3D NULL) {
  &n= bsp;         printf("[rte flow rule= ] successfully created a egress flow rule in port %u\n", port_id);
        }
 &nbs= p;  }
}

When I= try to run the above program, the flow rule validated successfully with `r= te_flow_validate()`, but failed on creating the flow with an error of `hard= ware refuses to create flow`.
[init flow rule] validated successfully.<= br>
[create flow rule] failed to crea= te flow rule, error: hardware refuses to create flow.
The same error arise when try to create the flow in `dpdk-testpmd` pr= ogram.
testpmd> flow isolate 0 true
testpmd> port start 0
port_flow_complain(): Caught PM= D error type 1 (cause unspecified): hardware refuses to create flow: Operat= ion not supported
Can anyone tell me whether= my code is correct or not?

Can anyon= e tell me whether my code is correct or not? and any idea how to use SEND_T= O_KERNEL Action on Mellanox CX-5 NIC's.

System specification.
     Operating System: Debian
     = ;OS Version: 12.7
     DPDK version: 24.07


Tha= nks and Regards,
Gopinath.



------=_Part_2023389_597917094.1730795004297--