int fdir_init(uint8_t port_id){ int return_value; struct rte_eth_fdir_info fdir_info; /* check fdir card support */ return_value = rte_eth_dev_filter_supported(port_id, RTE_ETH_FILTER_FDIR); if (return_value < 0) { RTE_LOG(CRIT,PORT,"FDIR not supported on port %-2d\n",port_id); return -1; } /* check filter is supported */ return_value = rte_eth_dev_filter_ctrl(port_id, RTE_ETH_FILTER_FDIR, RTE_ETH_FILTER_NOP, NULL ); rte_eth_dev_filter_ctrl(port_id, RTE_ETH_FILTER_FDIR, RTE_ETH_FILTER_INFO, &fdir_info); /* check fdir is activated */ if (fdir_info.mode == RTE_FDIR_MODE_PERFECT) { printf("MODE PERFECT RULE ENABLED\n"); } else if (fdir_info.mode == RTE_FDIR_MODE_SIGNATURE) { printf("MODE SIGNATURE ENABLED\n"); } else { RTE_LOG(CRIT,PORT,"FDIR not enabled on port %-2d\n",port_id); return -1; } if (return_value < 0){ RTE_LOG(ERR, PORT, "error FDIR : FILTER not supported," "error %i (%s)\n", rte_errno, strerror(rte_errno)); return rte_errno; } return 0; }
static inline void fdir_filter_add(uint8_t port_id, const char *addr, enum rte_eth_fdir_behavior behavior, uint32_t soft_id) { struct rte_eth_fdir_filter entry; uint32_t fdir_ip_addr; int ret = 0; ret = rte_eth_dev_filter_supported(port_id, RTE_ETH_FILTER_FDIR); if (ret < 0) { printf("flow director is not supported on port %u.\n", port_id); return; } memset(&entry, 0, sizeof(struct rte_eth_fdir_filter)); ret = inet_pton(AF_INET, addr, &fdir_ip_addr); if (ret <= 0) { if (ret == 0) { printf("Error: %s is not in presentation format\n", addr); return; } else if (ret == -1) { perror("inet_pton"); return; } } //printf("%d\n", behavior); //printf("%s, %u\n", addr, fdir_ip_addr); entry.input.flow_type = RTE_ETH_FLOW_NONFRAG_IPV4_TCP; //entry.input.flow_type = RTE_ETH_FLOW_IPV4; entry.input.flow.ip4_flow.dst_ip = fdir_ip_addr; //entry.input.flow.udp4_flow.src_port = rte_cpu_to_be_16(TCP_PORT); //entry.input.flow.udp4_flow.dst_port = rte_cpu_to_be_16(TCP_PORT); entry.input.flow.udp4_flow.dst_port = rte_cpu_to_be_16(0); entry.input.flow_ext.is_vf = 0; entry.action.behavior = behavior; entry.action.flex_off = 0; entry.action.report_status = RTE_ETH_FDIR_REPORT_ID; if (behavior == RTE_ETH_FDIR_ACCEPT) entry.action.rx_queue = PKT_ACCEPT_QUEUE; else entry.action.rx_queue = PKT_DROP_QUEUE; entry.soft_id = soft_id; ret = rte_eth_dev_filter_ctrl(port_id, RTE_ETH_FILTER_FDIR, RTE_ETH_FILTER_ADD, &entry); if (ret < 0) printf("flow director programming error: (%s)\n", strerror(-ret)); entry.soft_id = soft_id + 100; entry.input.flow.udp4_flow.dst_port = rte_cpu_to_be_16(0x1); ret = rte_eth_dev_filter_ctrl(port_id, RTE_ETH_FILTER_FDIR, RTE_ETH_FILTER_ADD, &entry); if (ret < 0) printf("flow director programming error: (%s)\n", strerror(-ret)); }