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, &param);
	ipvs_set_ipaddr(&param, 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<<shift) < sa_nlcore; shift++)
        ;
    if (shift >= 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的配置。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章