
一、基础架构类Q1. OVS 的整体架构内核态和用户态分别负责什么用户态ovs-vswitchd核心守护进程管 OpenFlow 流表、做慢路径决策、ovsdb-server配置库。内核态openvswitch.ko内核模块即 datapath数据路径只做快速转发 精确匹配缓存。分工用户态是大脑完整 OpenFlow 流水线、复杂精确匹配内核态缓存已生成的的高效流表快速转发。Q2. OpenFlow 流表和内核流表datapath flow是一回事吗OpenFlow 流表在ovs-vswitchd用户态支持多级流水线multi-table、复杂匹配和 action是规则源头。内核 datapath 流表内核里的缓存是 OpenFlow 流水线计算后的结果把多表流水线压平成一条 datapath 流只做匹配→执行 action。内核流表不是手动配置的是首包 upcall 后由用户态下发的。二、快慢路径 / upcall 类核心Q3. 描述一个报文第一次进入 OVS 的完整处理流程首包路径。报文进入内核 datapath查内核流表 → miss首包没有缓存。内核通过 upcallNetlink把包送到用户态ovs-vswitchd。用户态跑完整 OpenFlow 流水线多级流表匹配算出最终 action。用户态通过 Netlink 把结果下发一条 datapath 流到内核并让这个包按 action 执行packet_out。后续同类报文在内核直接命中缓存快速转发不再 upcall。Q4. 什么是 upcall为什么它开销大upcall 内核 datapath 未命中缓存时把报文/元数据经 Netlink 上送用户态决策的过程。开销大内核↔用户态上下文切换 拷贝 完整流水线计算。所以 OVS 性能优化的核心就是尽量减少 upcall提高内核缓存命中率。Q5. upcall 有哪几种类型MISS upcall流表未命中请求用户态决策最常见。ACTION upcalluserspace actionaction 明确要求把包送用户态如CONTROLLER、采样、部分 learn 等。三、缓存机制类重中之重Q6. OVS 的两级流缓存是什么microflow cache 和 megaflow cache 的区别Microflow cache精确匹配缓存早期设计key 是完整五元组等精确匹配exact match。一条流一个 entry命中率对短连接/大量流很差每条新连接都 miss。Megaflow cache通配匹配缓存现在的主力。带通配符wildcard mask的匹配一条 megaflow 可覆盖一批报文。通过只匹配真正影响转发决策的字段其它字段 wildcard大幅提高命中率、减少 upcall。现代 OVS 内核 datapath 用 megaflow用户态还有一层 microflow cacheEMC 做二次加速DPDK 场景更明显。Q7. megaflow 的 mask 是怎么来的为什么它能减少流表条目用户态跑流水线时会追踪这次决策到底看了哪些字段用了哪些 match 域。没被看的字段就打上 wildcard。于是一条 megaflow 覆盖所有这些字段取任意值、但关键字段相同的报文 → 一条顶多条条目更少、命中率更高。Q8. EMCExact Match Cache是什么主要在 OVS-DPDK用户态 datapath 里在 megaflow 之前再加一层精确匹配的小缓存命中最热的流避免 megaflow 的通配查找开销。内核 datapath 也有类似的microflow→megaflow两级思路。四、匹配与查找类Q9. 内核 datapath 用什么数据结构做通配符匹配TSSTuple Space Search元组空间搜索把相同 mask 的流归为一个 mask tuple每个 tuple 内做哈希精确查找遍历所有 tuple 取最高优先级命中。mask 种类越多要查的 tuple 越多查找越慢 → 所以控制 mask 数量很重要。Q10. datapath flow 的 key 包含哪些内容报文的解析字段集合in_port、以太头src/dst mac、ethertype、VLAN、L3IP src/dst、proto、tos、ttl、L4端口、flags、隧道元数据tun_id/tun_src/tun_dst如 VXLAN/Geneve、以及 recirc_id、ct 状态等。五、进阶特性类Q11. recirculationrecirc是什么为什么需要某些操作需要重新解析/多轮处理如剥掉隧道/VLAN 后再按内层匹配、连接跟踪后再决策。OVS 用 recirc_id 把处理分成多个阶段执行到某步后带着 recirc_id 重新进入 datapath 查表实现分段流水线。常见于隧道解封装、conntrack、MPLS、bond 哈希后再匹配。Q12. conntrack 在 datapath 里如何体现OVS 通过ct()action 调用内核 nf_conntrack给报文打上连接状态new/est/rel/inv。通常配合 recirc先ct()recirc 回来后再按 ct_state/ct_zone/ct_mark/ct_label 匹配 → 实现有状态防火墙/NAT。Q13. datapath 流表条目会一直存在吗如何老化不会。内核流有空闲超时老化ovs-vswitchd周期性 dump datapath 流的统计packet/byte/used 时间长时间无命中的流会被回收删除。这也是为什么ovs-dpctl dump-flows看到的流是动态变化的。Q14. 硬件卸载hw-offload时内核流表怎么变开启hw-offload后OVS 把 datapath 流通过 TC flower 下发到网卡硬件。命中的流在网卡里直接转发不进内核软件 datapath进一步降 CPU。之前你遇到的 mlx5Invalid action sequence就是某些 action 组合硬件不支持、卸载失败的表现。六、实操 / 排查类Q15. 常用查看内核流表的命令ovs-dpctl dump-flows # 直接看内核 datapath 流含 mask、statsrecirc_id(0),in_port(18),eth(srcfa:16:84:5b:69:d4,dstf2:01:0a:34:fb:c1),eth_type(0x0806),arp(sip10.52.251.197,tip10.52.251.193,op1/0xff,shafa:16:84:5b:69:d4,tha00:00:00:00:00:00), packets:20234, bytes:849828, used:21.378s, actions:userspace(pid4294967295,slow_path(action))recirc_id(0),in_port(33),eth(dstf2:01:c0:be:00:01),eth_type(0x0800),ipv4(dst172.0.0.0/252.0.0.0,proto6,ttl64,fragno), packets:41463, bytes:2736558, used:61.193s, flags:S, actions:droprecirc_id(0),tunnel(tun_id0x1f,src10.52.254.1,dst10.52.136.82,flags(-dfcsumkey)),in_port(1),eth(src10:70:fd:49:e8:cb,dstf2:01:a9:fe:00:c8),eth_type(0x0800),ipv4(dst10.52.251.9,proto6,ttl59,fragno), packets:7839772, bytes:425244996, used:0.704s, flags:SPR., actions:set(eth(srcf2:01:0a:34:fb:01,dstfa:16:ce:6a:dd:a8)),set(ipv4(ttl58)),35recirc_id(0),tunnel(tun_id0x1f,src10.52.254.1,dst10.52.136.82,flags(-dfcsumkey)),in_port(1),eth(srce8:eb:d3:43:40:11,dstf2:01:a9:fe:00:c8),eth_type(0x0800),ipv4(dst10.52.251.9,proto6,ttl58,fragno), packets:2317085, bytes:171060244, used:1.458s, flags:SFPR., actions:set(eth(srcf2:01:0a:34:fb:01,dstfa:16:ce:6a:dd:a8)),set(ipv4(ttl57)),35说明含义从 VXLAN 隧道进来、发往某内网 IP 的报文改写 MAC/TTL 后从 port 35 发出。逐段拆解一、匹配字段Match报文要满足这些才命中recirc_id(0)重入 ID 0表示这是第一轮处理未经过 recirculation。若是隧道解封装/conntrack 后再匹配会是非 0 值。这里 0 报文刚进 datapath 的原始阶段。tunnel(...)—— 隧道元数据说明是隧道收上来的包子字段含义tun_id0x1f隧道 ID 31十进制。VXLAN 即 VNI31src10.52.254.1外层隧道源 IP对端 VTEPdst10.52.136.82外层隧道目的 IP本机 VTEPflags(-dfcsumkey)隧道标志-df不设 DF允许分片csum带校验和key携带 tunnel key(VNI)有tunnel(...)段 这条流匹配的是从 VXLAN/Geneve 隧道解封装进来的内层报文。in_port(1)入端口 datapath port号 1通常是隧道口 vxlan_sys / 上行口。eth(src...,dst...)内层以太头srce8:eb:d3:43:40:11dstf2:01:a9:fe:00:c8eth_type(0x0800)以太类型 IPv4。ipv4(dst10.52.251.9,proto6,ttl58,fragno)子字段含义dst10.52.251.9目的 IP注意这里没匹配 src说明 src 被 wildcard 了proto6L4 协议 TCPttl58匹配 TTL58进来时的值fragno非分片包注意只列出的字段才是被匹配的没列出的字段如 ip src、L4 端口被 wildcardmegaflow 的通配这也是为什么这一条能覆盖大量报文。二、统计与状态packets:2317085, bytes:171060244该流累计命中 231 万包 / 约 171 MB——命中量很大是条热流。used:1.458s距上次命中过去 1.458 秒。这个值决定老化越小越活跃长时间不更新会被 revalidator 回收。flags:SFPR.TCP 连接中观察到的 TCP flag 汇总datapath 记录这条流见过哪些标志位常见字母S SYNF FINP PSHR RST末尾. 占位/其它表示这条流的报文里出现过 SYN/FIN/PSH/RST是一条正常有数据收发、且已看到连接建立与关闭迹象的 TCP 流。三、动作Actions命中后依次执行actions:set(eth(srcf2:01:0a:34:fb:01, dstfa:16:ce:6a:dd:a8)), // 改写内层源/目的 MACset(ipv4(ttl57)), // TTL 58 → 57路由跳数减135 // 从 datapath port 35 发出逐条set(eth(...))把内层以太头改成新的 src/dst MAC。新dstfa:16:ce:6a:dd:a8是 OpenStack/虚拟化常见的fa:16:...系列 MAC下一跳/目的虚机的 MAC。新srcf2:01:0a:34:fb:01是本网关口的 MAC。这就是三层转发/路由的典型行为改 MAC 换下一跳。set(ipv4(ttl57))TTL 减 158→57符合经过一次路由跳的语义。35output 到 datapath port 35目的虚机/容器对应的 vport 或下一段口。四、整体语义一句话读懂VNI31 的 VXLAN 隧道对端 VTEP10.52.254.1→ 本机10.52.136.82解封装后得到一个发往10.52.251.9的 TCP 报文OVS 对它做三层转发改写源/目的 MAC 为网关口和目的虚机 MAC、TTL 减 1然后从 port 35 送到目的虚机。这是典型的 隧道入 → L3 路由 → 送本地虚机 转发路径overlay 网络里跨节点东西向流量在目的节点的处理。五、几个可延伸的排查点确认 port 35 是谁ovs-dpctl show或ovs-vsctl -- --columnsname,ofport list interface看 port 35 对应哪个 vport目的虚机 tap/vif。为何 TTL58 被精确匹配说明流水线里看了TTL可能有 TTL 相关判断所以它没被 wildcard这类精确字段会增加 megaflow mask 种类量大时影响查找性能。对照 OpenFlow 规则ovs-appctl ofproto/trace br-int flow可看这条 datapath 流是由哪些 OpenFlow 多表规则压平来的。src 被通配这条流不区分源 IP/端口说明转发决策只依赖目的 IP 隧道 TTL命中率高。ovs-appctl dpctl/dump-flows # 经 vswitchd信息更全ovs-appctl dpif/dump-flows br-intovs-ofctl dump-flows br-int # 看的是 OpenFlow 流表用户态规则不是内核流ovs-appctl upcall/show # 看 upcall/handler 统计ovs-appctl coverage/show # 看 upcall 次数等计数Q16. 怎么判断/追踪一条报文会怎么走ovs-appctl ofproto/trace br-int flow描述 # 模拟报文走完整流水线看命中哪些表、最终 action你们flowtraceCLI 的 arp/icmp/vxlan 就是封装了ofproto/trace。Q17. upcall 太多、CPU 高怎么排查优化ovs-appctl coverage/show看 upcall 计数是否飙升。原因常见mask 太多导致 megaflow 命中率低、大量短连接、频繁 recirc、conntrack 表压力。优化减少 wildcard 破坏避免不必要的精确匹配字段、开 hw-offload、调 handler/revalidator 线程数n-handler-threads/n-revalidator-threads。七、高频陷阱小题问题答案要点ovs-ofctl dump-flows和ovs-dpctl dump-flows区别前者用户态 OpenFlow 规则后者内核 datapath 缓存流水线压平后的结果内核流表条目是配置的还是学习的不是配置是首包 upcall 后用户态下发的缓存megaflow 为什么比 microflow 好带 wildcard一条覆盖一批减少条目与 upcall一条 OpenFlow 多表流水线在内核里是几条流压平成一条 datapath 流可能因 recirc 分成几段为什么隧道/conntrack 常伴随 recirc需要解封装/打状态后重新匹配