采用dpdk开发实现类似LVS这种负载均衡时,为了提高性能,session数据结构是per core的,这样可以避免cpu之间锁竞争。详细介绍可以参考https://zhuanlan.zhihu.com/p/24826649。里面详细介绍了为什么需要使用flow director。
int rte_eth_dev_fdir_add_signature_filter (uint8_t port_id, struct rte_fdir_filter *fdir_filter, uint8_t rx_queue)
int rte_eth_dev_fdir_update_signature_filter (uint8_t port_id, struct rte_fdir_filter *fdir_ftr, uint8_t rx_queue)
int rte_eth_dev_fdir_remove_signature_filter (uint8_t port_id, struct rte_fdir_filter *fdir_ftr)
int rte_eth_dev_fdir_get_infos (uint8_t port_id, struct rte_eth_fdir *fdir)
int rte_eth_dev_fdir_set_masks (uint8_t port_id, struct rte_fdir_masks *fdir_mask)
static struct rte_eth_conf port_conf = {
...
/* 这一项配置成这样 */
.fdir_conf = {
.mode = RTE_FDIR_MODE_SIGNATURE,
.pballoc = RTE_FDIR_PBALLOC_64K,
.status = RTE_FDIR_REPORT_STATUS,
.flexbytes_offset = 0x0,
.drop_queue = 127,
},
};
struct rte_fdir_masks masks;
masks.only_ip_flow = 1; //如果仅仅是对L3层进行fdir,此地方设置成1
masks.dst_ipv4_mask = dst_ipv4_mask;
masks.src_ipv4_mask = src_ipv4_mask;
masks.dst_port_mask = dst_port_mask;
masks.src_port_mask = src_port_mask;
rte_eth_dev_fdir_set_masks(portid, &masks);
enum rte_l4type {
RTE_FDIR_L4TYPE_NONE = 0, /**< None. */
RTE_FDIR_L4TYPE_UDP, /**< UDP. */
RTE_FDIR_L4TYPE_TCP, /**< TCP. */
RTE_FDIR_L4TYPE_SCTP, /**< SCTP. */
};
struct rte_fdir_filter filter;
filter.vlan_id = vlan_id;
filter.ip_dst.ipv4_addr = htonl(dst_ipv4_addr);
filter.port_dst = htons(port_dst);
filter.ip_src.ipv4_addr = htonl(src_ipv4_addr);
filter.port_src = htons(port_src);
filter.l4type = RTE_FDIR_L4TYPE_UDP ;//or RTE_FDIR_L4TYPE_TCP;
filter.iptype = RTE_FDIR_IPTYPE_IPV4;
rte_eth_dev_fdir_add_signature_filter(portid, &filter, queueid);
/* 一般一个port会分为多个queue,如:dpdk使用8个core进行处理,那么每个port可以创建8个queue,queueid从1-8开始。 */
删除filer比较简单:
rte_eth_dev_fdir_remove_signature_filter(portid ,&filter);
DKDP api:http://dpdk.org/doc/api-1.6/rte__ethdev_8h.html