openvswitch group hash实现代码分析
创始人
2024-03-01 08:00:26

代码分析

ovs版本是2.11.0,linux版本是linux-3.10.0-693.21.1.el7。

只拿ovs实现的group hash和dp_hash举例分析代码,通过一个点一个功能切入代码,漫无目的看代码是很难看懂的,必须带着一个疑问看代码,点多了全面开花,从点到面,慢慢就搞定代码了。

代码分析的场景就是一个虚拟机中curl一个vip。

ovs都说首包从datapath上送到vswitchd那就找找vswitchd从哪开始处理首包的。

main└─bridge_run└─bridge_reconfigure└─ofproto_create└─construct└─open_dpif_backer├─udpif_create|   └─dpif_register_upcall_cb//kernel为NULL,用于DPDK├─udpif_set_threads|  └─dpif_handlers_set└─udpif_start_threads└─udpif_upcall_handler├─dpif_recv|  └─dpif_netlink_recv|     └─dpif_netlink_recv__|        └─parse_odp_packet└─recv_upcalls

vswitchd启动时创建了udpif_start_threads几个thread,这几个thread循环调用recv_upcalls处理上送的首包。

再找datapath首包是在什么地方上送的。

#linux kernel datapath
ovs_vport_receive├─ovs_flow_key_extract|   └─key_extract└─ovs_dp_process_packet├─if ovs_flow_tbl_lookup_stats|   └─ovs_dp_upcall|      └─queue_userspace_packet|          └─ovs_nla_put_key|              └─__ovs_nla_put_key└─else ovs_execute_actions├─case OVS_ACTION_ATTR_OUTPUT└─do_output└─ovs_vport_send

首包来了先从skb上ovs_flow_key_extract生成flow key,再根据key查找 表ovs_flow_tbl_lookup_stats,查找不到,那就上送vswitchd。

vswitchd收到开始处理,包来的ofport是知道,这个ofport在哪个桥上是知道的,那就从这个桥的table 0开始查找,匹配上了就执行动作,如果碰到goto或者resubmit那么就换个table继续查找,如果碰到normal或者output patch port,那么就换桥了,现在假如到了br-tun桥了,继续从table 0开始查找,最后到了table 20,动作是group:1001,要执行pick_select_group。

如果是hash,找到bucket,然后xlate_group_bucket,安装流表,下发datapath执行动作。

如果是dp_hash,此时flow中在hash值为空,找不到bucket,找不到就触发ctx_trigger_recirculate_with_hash,来了一次freezing,而finish_freezing中给datapath下的消息中添加了两个动作OVS_ACTION_ATTR_HASH和OVS_ACTION_ATTR_RECIRC,安装一条流,这给条是这样的:

ufid:f4352588-1396-47a7-aff7-98ce54931e72, recirc_id(0),dp_hash(0/0),skb_priority(0/0),in_port(tap240cf299-12),skb_mark(0/0),ct_state(0/0),ct_zone(0/0),ct_mark(0/0),ct_label(0/0),eth(src=fa:16:3e:e5:cb:19,dst=fa:16:3e:ec:85:20),eth_type(0x0800),ipv4(src=0.0.0.0/0.0.0.0,dst=0.0.0.0/0.0.0.0,proto=0/0,tos=0/0,ttl=0/0,frag=no), packets:9, bytes:978, used:1.972s, flags:P., dp:ovs, actions:push_vlan(vid=30,pcp=0),hash(l4(0)),recirc(0x5a6)

包又下给了datapath。

recv_upcalls├─odp_flow_key_to_flow├─upcall_receive|  └─xlate_lookup|     └─xlate_lookup_ofproto_├─process_upcall| └─upcall_xlate|   ├─xlate_in_init|   ├─xlate_actions|   |  ├─rule_dpif_lookup_from_table|   |  |  └─rule_dpif_lookup_in_table|   |  ├─rule_get_actions|   |  └─do_xlate_actions|   |     ├─freeze_unroll_actions|   |     |  └─freeze_put_unroll_xlate|   |     ├─xlate_group_action|   |     |  ├─pick_select_group//报文第一次找不到bucket|   |     |  |  └─pick_dp_hash_select_group|   |     |  |     └─ctx_trigger_recirculate_with_hash|   |     |  └─xlate_group_bucket//第二次找到bucket才执行这里|   |     |     ├─ofpacts_execute_action_set|   |     |     └─do_xlate_actions//相当于递归了|   |     └─finish_freezing//报文第一次来执行这里|   |        ├─xlate_commit_actions|   |        |  └─commit_odp_actions|   |        └─finish_freezing__|   |           ├─recirc_alloc_id_ctx|   |           ├─把OVS_ACTION_ATTR_HASH和OVS_ACTION_ATTR_RECIRC下给datapath |   |           └─ctx_cancel_freeze|   └─ukey_create_from_upcall└─handle_upcalls└─dpif_operate├─ukey_install└─dpif_operate//给datapath安装流表和把skb发回内核├─if dpif_netlink_operate└─else dpif_execute_with_help└─odp_execute_actions├─计算hash└─dpif_execute_helper_cb└─dpif_operate         

继续看datapath接着怎么处理,匹配上刚才看的那条流了,计算hash值,执行recirc,又重头开始了,key要找不到了,再上送vswitchd。

ovs_packet_cmd_execute├─ovs_flow_key_extract_userspace├─ovs_nla_copy_actions└─ovs_execute_actions└─do_execute_actions├─case OVS_ACTION_ATTR_HASH|   └─execute_hash|       └─skb_get_hash|           └─__skb_get_hash└─case OVS_ACTION_ATTR_RECIRC└─ovs_dp_process_packet

vswitchd重复刚才的处理,这次key中多了个hash值,终于找到bucket了,又下了一条流,包再下发给datapath。

ufid:ee6e45b0-4e62-43e9-8a6c-87573ece1cc7, recirc_id(0x5a6),dp_hash(0x9/0xf),skb_priority(0/0),in_port(tap240cf299-12),skb_mark(0),ct_state(0/0),ct_zone(0/0),ct_mark(0/0),ct_label(0/0),eth(src=00:00:00:00:00:00/00:00:00:00:00:00,dst=00:00:00:00:00:00/00:00:00:00:00:00),eth_type(0x8100),vlan(vid=30,pcp=0),encap(eth_type(0x0800),ipv4(src=0.0.0.0/0.0.0.0,dst=0.0.0.0/0.0.0.0,proto=0/0,tos=0/0x3,ttl=0/0,frag=no)), packets:7, bytes:816, used:1.971s, flags:P., dp:ovs, actions:set(tunnel(tun_id=0x3e8,src=10.145.69.26,dst=10.162.143.7,ttl=64,tp_dst=4789,flags(df|key))),pop_vlan,vxlan_sys_4789

这次datapath成功匹配上了,执行ovs_execute_actions中的OVS_ACTION_ATTR_OUTPUT,最终调用到ovs_vport_send就发送出去了,ovs vxlan实现留下次代码分析再写,最近一个任务就是测试和分析ovs vxlan和物理交换机vxlan性能对比。

几个回合之后没包需要再传输了,刚才安装的datapath flow需要老化,老化又就是怎么实现的。

udpif_start_threads└─udpif_revalidator├─revalidate|   ├─dpif_flow_dump_next|   ├─udpif_get_n_flows|   ├─delete_op_init__|   └─push_dp_ops└─revalidator_sweep

问题

测试hash没有问题,但测试dp_hash时偶尔会出问题,tcp三次握手,syn包发送给了dpvs节点6,dpvs节点6给回复syn+ack,接着ack包居然发送给了dpvs节点7,后面就是两方不断重传,终于有一次push+ack发送到了dpvs节点6,后面又搞给了dpvs节点7,乱套了。

vswitchd的log中出现了两个hash时,并且recircid也在变,recirc_id再变说明datapath流表老化,流中的报文又重新upcall到用户态了。

内核execute_hash->skb_get_hash调用到flow_dissector计算hash时没有用到tcp flag,hash值不会变,内核出错的概念也不大。

不断抓包观察到是重传间隔时间越来越长,终于有一次push+ack包才回到dpvs节点6上,说明是datapath流表老化了,又上用户态,难道一个hash值是用户态计算的,另一个hash值是datapath计算的,但OVS_ACTION_ATTR_HASH没有用到SLOW_ACTION,是在内核态执行的,ovs用户态代码实现太多了,难道我漏看了什么,怀疑大概率还是一个hash值是用户态计算的,另一个在内核态计算的,代码注释中说用户态OVS_ACTION_ATTR_HASH只用于bond,即使和datapath hash值不同也没有问题,可能会导致报文乱序,但交换机不在乎,但这儿的使用场景不行,包发给错的dpvs节点,dpvs节点没有session,包直接丢了,一条流只能hash到一个dpvs节点。在代码在还是没有看明白什么地方设置LOW_ACTION的。

原文链接“https://zhuanlan.zhihu.com/p/337143779” 

(免费订阅,永久学习)学习地址: Dpdk/网络协议栈/vpp/OvS/DDos/NFV/虚拟化/高性能专家-学习视频教程-腾讯课堂

更多DPDK相关学习资料有需要的可以自行报名学习,免费订阅,永久学习,或点击这里加qun免费
领取,关注我持续更新哦! ! 

相关内容

热门资讯

demo什么意思 demo版本... 618快到了,各位的小金库大概也在准备开闸放水了吧。没有小金库的,也该向老婆撒娇卖萌服个软了,一切只...
应用未安装解决办法 平板应用未... ---IT小技术,每天Get一个小技能!一、前言描述苹果IPad2居然不能安装怎么办?与此IPad不...
脚上的穴位图 脚面经络图对应的... 人体穴位作用图解大全更清晰直观的标注了各个人体穴位的作用,包括头部穴位图、胸部穴位图、背部穴位图、胳...
世界上最漂亮的人 世界上最漂亮... 此前在某网上,选出了全球265万颜值姣好的女性。从这些数量庞大的女性群体中,人们投票选出了心目中最美...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
埃菲尔铁塔在哪 中国仿建埃菲尔... 2019年4月26日,广西南宁市,街头惊现一座巨型山寨版埃菲尔铁塔,高约20米,白色塔身,造型逼真,...
猫咪吃了塑料袋怎么办 猫咪误食... 你知道吗?塑料袋放久了会长猫哦!要说猫咪对塑料袋的喜爱程度完完全全可以媲美纸箱家里只要一有塑料袋的响...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...
埃菲尔铁塔在哪 中国仿建埃菲尔... 2019年4月26日,广西南宁市,街头惊现一座巨型山寨版埃菲尔铁塔,高约20米,白色塔身,造型逼真,...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
长白山自助游攻略 吉林长白山游... 昨天介绍了西坡的景点详细请看链接:一个人的旅行,据说能看到长白山天池全凭运气,您的运气如何?今日介绍...
应用未安装解决办法 平板应用未... ---IT小技术,每天Get一个小技能!一、前言描述苹果IPad2居然不能安装怎么办?与此IPad不...
脚上的穴位图 脚面经络图对应的... 人体穴位作用图解大全更清晰直观的标注了各个人体穴位的作用,包括头部穴位图、胸部穴位图、背部穴位图、胳...