dpvs fdir的使用(笔记)

添加laddr的时候:

int ipvs_add_laddr(ipvs_service_t *svc, ipvs_laddr_t * laddr)
{
	struct dp_vs_laddr_conf conf;
	struct inet_addr_param param;

	ipvs_fill_laddr_conf(svc, laddr, &conf);
	ipvs_fill_ipaddr_conf(1, 0, laddr, ¶m);
	ipvs_set_ipaddr(¶m, 1);

	return dpvs_setsockopt(SOCKOPT_SET_LADDR_ADD, &conf, sizeof(conf));
}
其中函数 ipvs_fill_ipaddr_conf 会做如下操作:
param->ifa_entry.flags |= IFA_F_SAPOOL;

此接口在后续的添加的时候,在函数ifa_entry_add

    if (ifa->flags & IFA_F_SAPOOL) {
        err = sa_pool_create(ifa, 0, 0);
        if (err != EDPVS_OK)
            goto del_route;
    }

函数 sa_pool_create 会调用dpdk创建fdir规则

    err = sa_add_filter(ifa->af, ifa->idev->dev, cid, &ifa->addr,
                        fdir->port_base, filtids); /* thread-safe ? */

其中两个重要的参数,一个是接口的地址,即配置的lan ip, laddr的地址,另一个dest port参数初始化的位置在函数sa_pool_init中。

此函数代码如下:

int sa_pool_init(void)
{
    int shift;
    lcoreid_t cid;
    uint16_t port_base;

    /* enabled lcore should not change after init */
    netif_get_slave_lcores(&sa_nlcore, &sa_lcore_mask);

    /* how many mask bits needed ? */
    for (shift = 0; (0x1<= 16)
        return EDPVS_INVAL; /* bad config */

    port_base = 0;
    for (cid = 0; cid < DPVS_MAX_LCORE; cid++) {
        if (cid >= 64 || !(sa_lcore_mask & (1L << cid)))
            continue;
        assert(rte_lcore_is_enabled(cid) && cid != rte_get_master_lcore());

        sa_fdirs[cid].mask = ~((~0x0) << shift);
        sa_fdirs[cid].lcore = cid;
        sa_fdirs[cid].port_base = htons(port_base);
        sa_fdirs[cid].soft_id = 0;

        port_base++;
    }

    return EDPVS_OK;
}

函数的逻辑如下:
如果使用1个core,则mask = 0x0, port_base = 0; 即匹配所有dport
如果使用2个core,则mask = 0x1,
core0: port_base = 0x0
core1: port_base = 0x1
如果使用4个core,则mask = 0x11,
core0: port_base = 0x0
core1: port_base = 0x1
core2: port_base = 0x2
core3: port_base = 0x3
以此类推。
函数中调用sa_pool_alloc_hash来初始化了每个core上可以使用的port。

网卡的初始化位于文件netif.c中,其中比较重要的数据如下:

// 定义RSS及FDIR的默认设置
static struct rte_eth_conf default_port_conf = {
    .rxmode = {
        .mq_mode        = ETH_MQ_RX_RSS,
        .max_rx_pkt_len = ETHER_MAX_LEN,
        .split_hdr_size = 0,
        .offloads = DEV_RX_OFFLOAD_IPV4_CKSUM,
    },
    .rx_adv_conf = {
        .rss_conf = {
            .rss_key = NULL,
            .rss_hf  = /*ETH_RSS_IP*/ ETH_RSS_TCP,
        },
    },
    .txmode = {
        .mq_mode = ETH_MQ_TX_NONE,
    },
    .fdir_conf = {
    ....

在函数netif_port_start中设置了port的dpdk的rss配置及queue的配置。

你可能感兴趣的:(DPVS)