添加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的配置。