<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html><head><meta content="text/html;charset=UTF-8" http-equiv="Content-Type"></head><body ><div style="font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 10pt;"><div><div style="font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 10pt"><div>Hi,<br><br> I'm new to DPDK, and have been working on creating flow rules by using DPDK, to steer traffic to the kernel.<br><br> To understand the functionality of the Mellanox Bifuracted drive, i attempted to steer ICMP packets 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 <a href="https://doc.dpdk.org/guides/howto/rte_flow.html" rel="noreferer" target="_blank">(refrenced from from API examples)</a> the flow created successfully without an error.</div><div><br></div><div> However the issue arises when I attempt to use the RTE_FLOW_ACTION_TYPE_SEND_TO_KERNEL, which results in an error.<br></div><div><br></div><div>Below the sample code.<br><br> 1. functions to validate and create flow rule.</div><div><blockquote style="border: 1px solid rgb(204, 204, 204); padding: 7px; background-color: rgb(255, 255, 255);"><div>static ::rte_flow* create_flow(uint16_t port_id, rte_flow_attr& attr, rte_flow_item& pattern, rte_flow_action& actions) {<br></div><div> rte_flow_error error;<br></div><div> auto flow = rte_flow_create(port_id, &attr, &pattern, &actions, &error);<br></div><div> if (!flow) {<br></div><div> printf("[create flow rule] failed to create flow rule, error: %s.\n", error.message);<br></div><div> }<br></div><div> return flow;<br></div><div>}<br></div><div><br></div><div>bool validate_flow(uint16_t port_id, rte_flow_attr& attr, rte_flow_item& pattern, rte_flow_action& action) {<br></div><div> rte_flow_error error;<br></div><div> auto res = rte_flow_validate(port_id, &attr, &pattern, &action, &error);<br></div><div> if (res < 0) {<br></div><div> printf("[validate flow rule] validate flow failed, error: %s\n", error.message);<br></div><div> return false;<br></div><div> }<br></div><div> return true;<br></div><div>}<br></div></blockquote></div></div><div><br></div><div> 2. function to enable isolated mode on network port.<br></div><div><blockquote style="border: 1px solid rgb(204, 204, 204); padding: 7px; background-color: rgb(255, 255, 255);"><div>bool enable_isolated_mode(uint16_t port_id) {<br></div><div> rte_flow_error error;<br></div><div><br></div><div> // enable isolated mode.<br></div><div> if (rte_flow_isolate(port_id, 1, &error) < 0) {<br></div><div> printf("[isolated mode] failed to enable isolated mode on port %u, error: %s\n", port_id, error.message);<br></div><div> return false;<br></div><div> }<br></div><div><br></div><div> printf("[isolated mode] isolated mode enabled on port %u\n", port_id);<br></div><div> return true;<br></div><div>}<br></div></blockquote></div><div><br></div><div><div> 3. port initialization function.<br></div><blockquote style="border: 1px solid rgb(204, 204, 204); padding: 7px; background-color: rgb(255, 255, 255);"><div>static inline int<br></div><div>port_initilization(uint16_t port, rte_mempool *mbuf_pool) {<br></div><div> rte_eth_conf port_conf;<br></div><div><br></div><div> if (!rte_eth_dev_is_valid_port(port)) {<br></div><div> printf("[port init] port %u is not a valid port\n", port);<br></div><div> return -1;<br></div><div> }<br></div><div> if (!enable_isolated_mode(port)) {<br></div><div> return -1;<br></div><div> }<br></div><div> memset(&port_conf, 0, sizeof(rte_eth_conf));<br></div><div> rte_eth_dev_info device_info;<br></div><div> auto retval = rte_eth_dev_info_get(port, &device_info);<br></div><div> if (retval != 0) {<br></div><div> printf("[pirt init] getting device(port %u) info, error: %d [%s]\n", port, rte_errno, ::rte_strerror(rte_errno));<br></div><div> return retval;<br></div><div> }<br></div><div><br></div><div> if (device_info.tx_offload_capa & RTE_ETH_TX_OFFLOAD_MBUF_FAST_FREE)<br></div><div> port_conf.txmode.offloads |= RTE_ETH_TX_OFFLOAD_MBUF_FAST_FREE;<br></div><div><br></div><div> uint16_t rx_rings = 1;<br></div><div> uint16_t tx_rings = 1;<br></div><div> retval = rte_eth_dev_configure(port, rx_rings, tx_rings, &port_conf);<br></div><div> if (retval != 0) {<br></div><div> printf("[port init] failed to configure port(%u), error: %d [%s]\n", port, rte_errno, ::rte_strerror(rte_errno));<br></div><div> return retval;<br></div><div> }<br></div><div><br></div><div> uint16_t nb_rxd = RX_RING_SIZE;<br></div><div> uint16_t nb_txd = TX_RING_SIZE;<br></div><div> retval = rte_eth_dev_adjust_nb_rx_tx_desc(port, &nb_rxd, &nb_txd);<br></div><div> if (retval != 0) {<br></div><div> printf("[port init] rte_eth_dev_adjust failed, error: %d [%s]\n", rte_errno, ::rte_strerror(rte_errno));<br></div><div> return retval;<br></div><div> }<br></div><div><br></div><div> for (auto q = 0; q < rx_rings; q++) {<br></div><div> retval = rte_eth_rx_queue_setup(port, q, nb_rxd, rte_eth_dev_socket_id(port), NULL, mbuf_pool);<br></div><div> if (retval < 0)<br></div><div> return retval;<br></div><div> }<br></div><div><br></div><div> auto tx_conf = device_info.default_txconf;<br></div><div> tx_conf.offloads = port_conf.txmode.offloads;<br></div><div> for (auto q = 0; q < tx_rings; q++) {<br></div><div> retval = rte_eth_tx_queue_setup(port, q, nb_txd, rte_eth_dev_socket_id(port), &tx_conf);<br></div><div> if (retval < 0)<br></div><div> return retval;<br></div><div> }<br></div><div><br></div><div> ::rte_ether_addr addr;<br></div><div> retval = rte_eth_macaddr_get(port, &addr);<br></div><div> if (retval != 0)<br></div><div> return retval;<br></div><div><br></div><div> retval = rte_eth_dev_start(port);<br></div><div> if (retval != 0) {<br></div><div> printf("[port init] starting port %u failed, error: %d [%s]\n", port, rte_errno, rte_strerror(rte_errno));<br></div><div> return retval;<br></div><div> }<br></div><div> printf("[port init] successfully started port: %u\n", port);<br></div><div> printf("port %u MAC: %02" PRIx8 " %02" PRIx8 " %02" PRIx8 " %02" PRIx8 " %02" PRIx8 " %02" PRIx8 "\n", port, RTE_ETHER_ADDR_BYTES(&addr));<br></div><div> init_ingress_flow_rules(port);<br></div><div> init_egress_flow_rule(port);<br></div><div><br></div><div> return 0;<br></div><div>}<br></div></blockquote></div><div><br></div><div> 4. Flow rule</div></div><div><blockquote style="border: 1px solid rgb(204, 204, 204); padding: 7px; background-color: rgb(255, 255, 255);"><div>static void init_ingress_flow_rule(uint32_t port_id) {<br></div><div> rte_flow_attr attr = {0};<br></div><div> rte_flow_item pattern[4];<br></div><div> rte_flow_action action[2];<br></div><div><br></div><div> attr.ingress = 1;<br></div><div> memset(pattern, 0, sizeof pattern);<br></div><div> rte_flow_item_eth eth_spec;<br></div><div> rte_flow_item_eth eth_mask;<br></div><div> memset(ð_spec, 0, sizeof eth_spec);<br></div><div> memset(ð_mask, 0, sizeof eth_mask);<br></div><div> pattern[0].type = RTE_FLOW_ITEM_TYPE_ETH;<br></div><div> pattern[0].spec = ð_spec;<br></div><div><br></div><div> rte_flow_item_ipv4 ipv4_spec;<br></div><div> rte_flow_item_ipv4 ipv4_mask;<br></div><div> memset(&ipv4_spec, 0, sizeof ipv4_spec);<br></div><div> memset(&ipv4_mask, 0, sizeof ipv4_mask);<br></div><div> pattern[1].type = RTE_FLOW_ITEM_TYPE_IPV4;<br></div><div> pattern[1].spec = &ipv4_spec;<br></div><div> pattern[1].mask = &ipv4_mask;<br></div><div><br></div><div> rte_flow_item_icmp icmp_spec;<br></div><div> rte_flow_item_icmp icmp_mask;<br></div><div> memset(&icmp_spec, 0, sizeof icmp_spec);<br></div><div> memset(&icmp_mask, 0, sizeof icmp_mask);<br></div><div> icmp_spec.hdr.icmp_type = 0;<br></div><div> pattern[2].type = RTE_FLOW_ITEM_TYPE_ICMP;<br></div><div> pattern[2].spec = &icmp_spec;<br></div><div> pattern[2].mask = &icmp_mask;<br></div><div> pattern[3].type = RTE_FLOW_ITEM_TYPE_END;<br></div><div><br></div><div> action[0].type = RTE_FLOW_ACTION_TYPE_SEND_TO_KERNEL;<br></div><div> action[1].type = RTE_FLOW_ACTION_TYPE_END;<br></div><div><br></div><div> if (validate_flow(port_id, attr, pattern[0], action[0])) {<br></div><div> printf("[init flow rule] validated successfully.\n");<br></div><div> auto flow = create_flow(port_id, attr, pattern[0], action[0]);<br></div><div> if (flow != NULL) {<br></div><div> printf("[rte flow rule] successfully created a egress flow rule in port %u\n", port_id);<br></div><div> }<br></div><div> }<br></div><div>}<br></div></blockquote><div><br></div><div>When I try to run the above program, the flow rule validated successfully with `rte_flow_validate()`, but failed on creating the flow with an error of `hardware refuses to create flow`.<br></div><blockquote style="border: 1px solid rgb(204, 204, 204); padding: 7px; background-color: rgb(255, 255, 255);"><div style="line-height: 1.2;">[init flow rule] validated successfully.<br></div><div style="line-height: 1.2;">[create flow rule] failed to create flow rule, error: hardware refuses to create flow.<br></div></blockquote><div>The same error arise when try to create the flow in `dpdk-testpmd` program.<br></div><blockquote style="border: 1px solid rgb(204, 204, 204); padding: 7px; background-color: rgb(255, 255, 255);"><div style="line-height: 1.2;">testpmd> flow isolate 0 true<br></div><div style="line-height: 1.2;">testpmd> port start 0<br></div><div style="line-height: 1.2;"><span style="color: rgb(0, 0, 0); font-family: tahoma, arial, helvetica, sans-serif; font-size: 16px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; white-space: normal; background-color: rgb(255, 255, 255); text-decoration-thickness: initial; text-decoration-style: initial; text-decoration-color: initial; display: inline !important; float: none;"><span class="font" style="font-family: verdana;"><span class="size" style="font-size: 13.333333333333332px">testpmd> flow create 0 ingress pattern eth / ipv4 / icmp / end actions send_to_kernel / end</span></span></span><br></div><div style="line-height: 1.2;"><span style="color: rgb(0, 0, 0); font-family: tahoma, arial, helvetica, sans-serif; font-size: 16px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; white-space: normal; background-color: rgb(255, 255, 255); text-decoration-thickness: initial; text-decoration-style: initial; text-decoration-color: initial; display: inline !important; float: none;"><span style="color: rgb(0, 0, 0); font-family: tahoma, arial, helvetica, sans-serif; font-size: 16px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; white-space: normal; background-color: rgb(255, 255, 255); text-decoration-thickness: initial; text-decoration-style: initial; text-decoration-color: initial; display: inline !important; float: none;"><span class="font" style="font-family: verdana;"><span class="size" style="font-size: 13.333333333333332px">port_flow_complain(): Caught PMD error type 1 (cause unspecified): hardware refuses to create flow: Operation not supported</span></span></span></span><br>Can anyone tell me whether my code is correct or not?</div></blockquote><div><br></div><div>Can anyone tell me whether my code is correct or not? and any idea how to use SEND_TO_KERNEL Action on Mellanox CX-5 NIC's.<br><br>System specification.<br><br> Operating System: Debian</div><div> OS Version: 12.7<br> DPDK version: 24.07<br><br><br>Thanks and Regards,<br>Gopinath.<br></div></div><div><div><br></div></div><div><div style="font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 10pt"><div class="x_506015979zmail_signature_below"><div id="" data-sigid="8035361000000008028" data-zbluepencil-ignore="true"><div><p><span class="colour" style="color:rgb(42, 42, 42)">Sent using <a target="_blank" style="color: rgb(89, 143, 222);">Zoho Mail</a></span><br></p></div></div></div></div></div><div><br></div></div><br></body></html>