static ::rte_flow* create_flow(uint16_t port_id, rte_flow_attr& attr, rte_flow_item& pattern, rte_flow_action& actions) {rte_flow_error error;auto flow = rte_flow_create(port_id, &attr, &pattern, &actions, &error);if (!flow) {printf("[create flow rule] failed to create flow rule, error: %s.\n", error.message);}return flow;}bool validate_flow(uint16_t port_id, rte_flow_attr& attr, rte_flow_item& pattern, rte_flow_action& action) {rte_flow_error error;auto res = rte_flow_validate(port_id, &attr, &pattern, &action, &error);if (res < 0) {printf("[validate flow rule] validate flow failed, error: %s\n", error.message);return false;}return true;}
bool enable_isolated_mode(uint16_t port_id) {rte_flow_error error;// enable isolated mode.if (rte_flow_isolate(port_id, 1, &error) < 0) {printf("[isolated mode] failed to enable isolated mode on port %u, error: %s\n", port_id, error.message);return false;}printf("[isolated mode] isolated mode enabled on port %u\n", port_id);return true;}
static inline intport_initilization(uint16_t port, rte_mempool *mbuf_pool) {rte_eth_conf port_conf;if (!rte_eth_dev_is_valid_port(port)) {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 device_info;auto retval = rte_eth_dev_info_get(port, &device_info);if (retval != 0) {printf("[pirt init] getting device(port %u) info, error: %d [%s]\n", port, rte_errno, ::rte_strerror(rte_errno));return retval;}if (device_info.tx_offload_capa & RTE_ETH_TX_OFFLOAD_MBUF_FAST_FREE)port_conf.txmode.offloads |= RTE_ETH_TX_OFFLOAD_MBUF_FAST_FREE;uint16_t rx_rings = 1;uint16_t tx_rings = 1;retval = rte_eth_dev_configure(port, rx_rings, tx_rings, &port_conf);if (retval != 0) {printf("[port init] failed to configure port(%u), error: %d [%s]\n", port, rte_errno, ::rte_strerror(rte_errno));return retval;}uint16_t nb_rxd = RX_RING_SIZE;uint16_t nb_txd = TX_RING_SIZE;retval = rte_eth_dev_adjust_nb_rx_tx_desc(port, &nb_rxd, &nb_txd);if (retval != 0) {printf("[port init] rte_eth_dev_adjust failed, error: %d [%s]\n", rte_errno, ::rte_strerror(rte_errno));return retval;}for (auto q = 0; q < rx_rings; q++) {retval = rte_eth_rx_queue_setup(port, q, nb_rxd, rte_eth_dev_socket_id(port), NULL, mbuf_pool);if (retval < 0)return retval;}auto tx_conf = device_info.default_txconf;tx_conf.offloads = port_conf.txmode.offloads;for (auto q = 0; q < tx_rings; q++) {retval = rte_eth_tx_queue_setup(port, q, nb_txd, rte_eth_dev_socket_id(port), &tx_conf);if (retval < 0)return retval;}::rte_ether_addr addr;retval = rte_eth_macaddr_get(port, &addr);if (retval != 0)return retval;retval = rte_eth_dev_start(port);if (retval != 0) {printf("[port init] starting port %u failed, error: %d [%s]\n", port, rte_errno, rte_strerror(rte_errno));return retval;}printf("[port init] successfully started port: %u\n", port);printf("port %u MAC: %02" PRIx8 " %02" PRIx8 " %02" PRIx8 " %02" PRIx8 " %02" PRIx8 " %02" PRIx8 "\n", port, RTE_ETHER_ADDR_BYTES(&addr));init_ingress_flow_rules(port);init_egress_flow_rule(port);return 0;}
static void init_ingress_flow_rule(uint32_t port_id) {rte_flow_attr attr = {0};rte_flow_item pattern[4];rte_flow_action action[2];attr.ingress = 1;memset(pattern, 0, sizeof pattern);rte_flow_item_eth eth_spec;rte_flow_item_eth eth_mask;memset(ð_spec, 0, sizeof eth_spec);memset(ð_mask, 0, sizeof eth_mask);pattern[0].type = RTE_FLOW_ITEM_TYPE_ETH;pattern[0].spec = ð_spec;rte_flow_item_ipv4 ipv4_spec;rte_flow_item_ipv4 ipv4_mask;memset(&ipv4_spec, 0, sizeof ipv4_spec);memset(&ipv4_mask, 0, sizeof ipv4_mask);pattern[1].type = RTE_FLOW_ITEM_TYPE_IPV4;pattern[1].spec = &ipv4_spec;pattern[1].mask = &ipv4_mask;rte_flow_item_icmp icmp_spec;rte_flow_item_icmp icmp_mask;memset(&icmp_spec, 0, sizeof icmp_spec);memset(&icmp_mask, 0, sizeof icmp_mask);icmp_spec.hdr.icmp_type = 0;pattern[2].type = RTE_FLOW_ITEM_TYPE_ICMP;pattern[2].spec = &icmp_spec;pattern[2].mask = &icmp_mask;pattern[3].type = RTE_FLOW_ITEM_TYPE_END;action[0].type = RTE_FLOW_ACTION_TYPE_SEND_TO_KERNEL;action[1].type = RTE_FLOW_ACTION_TYPE_END;if (validate_flow(port_id, attr, pattern[0], action[0])) {printf("[init flow rule] validated successfully.\n");auto flow = create_flow(port_id, attr, pattern[0], action[0]);if (flow != NULL) {printf("[rte flow rule] successfully created a egress flow rule in port %u\n", port_id);}}}
[init flow rule] validated successfully.[create flow rule] failed to create flow rule, error: hardware refuses to create flow.
testpmd> flow isolate 0 truetestpmd> port start 0testpmd> flow create 0 ingress pattern eth / ipv4 / icmp / end actions send_to_kernel / endport_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?
Sent using Zoho Mail