ZBLOG

请具体分析这个函数 static inline void fast_path_processing(struct dp_netdev_pmd_thread *pmd, struct dp_packet_batch *packets_, struct netdev_flow_key **keys, struct packet_batch_per_flow batche...

该函数是 OvS(Open vSwitch) 中的一个静态内联函数,用于进行快速路径处理。具体分析如下:

参数说明:

  • pmd:指向 dp_netdev_pmd_thread 结构体的指针。
  • packets_:指向 dp_packet_batch 结构体的指针,表示待处理的数据包批量。
  • keys:指向 netdev_flow_key 指针数组的指针,用于存储每个数据包对应的流表键。
  • batches[]:packet_batch_per_flow 数组,表示每个流表规则匹配到的数据包批量。
  • n_batches:size_t 类型的指针,表示 batches 数组中有多少个元素。
  • in_port:ODP 端口号。

函数实现:

首先获取待处理数据包数量 cnt,并定义 PKT_ARRAY_SIZE 变量为 cnt 或 NETDEV_MAX_BURST(如果是 Checker 或 MSVC,则定义为 NETDEV_MAX_BURST)。然后声明一些变量和结构体指针:

struct dp_packet *packet; struct dpcls *cls; struct dpcls_rule *rules[PKT_ARRAY_SIZE]; struct dp_netdev *dp = pmd->dp; int upcall_ok_cnt = 0, upcall_fail_cnt = 0; int lookup_cnt = 0, add_lookup_cnt; bool any_miss;

接下来遍历所有待处理数据包,并计算出每个流表键 netdev_flow_key 的长度:

for (size_t i = 0; i < cnt; i++) {

  1. /* Key length is needed in all the cases, hash computed on demand. */
  2. keys[i]->len = netdev_flow_key_size(miniflow_n_values(&keys[i]->mf));

}

然后获取 in_port 对应的分类器 cls,如果 cls 存在,则根据匹配规则在 cls 中进行匹配。如果有 miss 的数据包,则判断是否能够成功获得读写锁:

if (OVS_LIKELY(cls)) {

  1. any_miss = !dpcls_lookup(cls, (const struct netdev_flow_key **)keys,
  2. rules, cnt, &lookup_cnt);

} else {

  1. any_miss = true;
  2. memset(rules, 0, sizeof(rules));

} if (OVS_UNLIKELY(any_miss) && !fat_rwlock_tryrdlock(&dp->upcall_rwlock)) {

如果成功获得读写锁,则遍历所有待处理数据包,分别进行处理。对于已经匹配到规则的数据包,直接跳过;对于没有匹配到规则的数据包,先尝试在缓存中查找该流表键是否已经存在,若存在则将其加入 lookup_cnt 中,并将对应的规则添加到 rules 数组中;否则调用 handle_packet_upcall 函数进行上报处理。

如果无法获得读写锁,则直接遍历所有待处理数据包并删除它们:

DP_PACKET_BATCH_FOREACH (i, packet, packets) {

  1. if (OVS_UNLIKELY(!rules[i])) {
  2. dp_packet_delete(packet);
  3. upcall_fail_cnt++;
  4. }

}

最后再次遍历所有待处理数据包,并根据匹配到的规则将它们添加到相应的 batches 中:

DP_PACKET_BATCH_FOREACH (i, packet, packets) {

  1. struct dp_netdev_flow *flow;
  2. if (OVS_UNLIKELY(!rules[i])) {
  3. continue;
  4. }
  5. flow = dp_netdev_flow_cast(rules[i]);
  6. uint32_t hash = dp_netdev_flow_hash(&flow->ufid);
  7. smc_insert(pmd, keys[i], hash);
  8. emc_probabilistic_insert(pmd, keys[i], flow);
  9. dp_netdev_queue_batches(packet, flow,
  10. miniflow_get_tcp_flags(&keys[i]->mf),
  11. batches, n_batches);

}

最后更新性能计数器,并结束函数执行。

本站部分文章来源于网络,版权归原作者所有,如有侵权请联系站长删除。
转载请注明出处:https://sdn.0voice.com/?id=920

分享:
扫描分享到社交APP
上一篇
下一篇
发表列表
游客 游客
此处应有掌声~
评论列表

还没有评论,快来说点什么吧~

联系我们

在线咨询: 点击这里给我发消息

微信号:3007537140

上班时间: 10:30-22:30

关注我们
x

注册

已经有帐号?