Post

DPDK 初学(8) IPv4 Multicast Sample

关键函数

rte_eth_allmulticast_enable

前面的流程和ip_fragmentation基本没差,这里也就不展开了,直到这个函数。

该函数用于启动某个port的多播功能。

init_mcast_hash

结构很简单,创建一个rte_fbk_hash_table然后向里面添加key即可。fbk(four byte keys)

1
2
3
4
5
6
7
8
9
mcast_hash_params.socket_id = rte_socket_id();
mcast_hash = rte_fbk_hash_create(&mcast_hash_params);
for (i = 0; i < RTE_DIM(mcast_group_table); i++) {
  if (rte_fbk_hash_add_key(mcast_hash,
   mcast_group_table[i].ip,
   mcast_group_table[i].port_mask) < 0) {
   return -1;
  }
 }

mcast_forward

去掉以太网头,获取dst_addr,开始查表。检查是否需要clone

1
2
3
4
5
6
7
8
9
if (!RTE_IS_IPV4_MCAST(dest_addr) ||
     (hash = rte_fbk_hash_lookup(mcast_hash, dest_addr)) <= 0 ||
     (port_mask = hash & enabled_port_mask) == 0) {
  rte_pktmbuf_free(m);
  return;
 }
...
use_clone = (port_num <= MCAST_CLONE_PORTS &&
     m->nb_segs <= MCAST_CLONE_SEGS);

开始进行多播转发,其中的mcast_out_pkt就是关键,通过m来构造mc这个pkt。其中通过参数use_clone来控制构造的细节,一种是clone一种是增加引用计数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
dst_eth_addr.as_int = ETHER_ADDR_FOR_IPV4_MCAST(dest_addr);
/* >8 End of constructing destination ethernet address. */

/* Packets dispatched to destination ports. 8< */
for (port = 0; use_clone != port_mask; port_mask >>= 1, port++) {
 /* Prepare output packet and send it out. */
 if ((port_mask & 1) != 0) {
  if (likely ((mc = mcast_out_pkt(m, use_clone)) != NULL))
   mcast_send_pkt(mc, &dst_eth_addr.as_addr,
     qconf, port);
  else if (use_clone == 0)
   rte_pktmbuf_free(m);
 }
}

关键流程

没啥好说的,流程清晰易懂。完全可以对照ip_fragmentation。

This post is licensed under CC BY 4.0 by the author.