OVS 流表offload


原文鏈接:https://www.dazhuanlan.com/2019/12/31/5e0af1858dada/

最近開始調研網卡的OVS流表offload功能,所以目前查看一下OVS這塊是怎么做的。

從上面可以看到OVS主要通過netlink發送給網口,接下來我們看一下網卡驅動做了一些什么,因為在做Mellanox家的網卡,所以這里查看代碼就查看mlx5_core的驅動代碼。

首先是開啟offload,Mellanox有兩種方案開啟offload,設置方法不一樣,但是實質是一致的,就是把eswitch_mode配置為switchdev,分別看一下:

第一種配置方法為devlink dev eswitch set pci/${PCI_ADDR} mode switchdev,這是中間一些版本的配置,它對應的代碼路徑如下:

eswitch_mode_set-->mlx5_devlink_eswitch_mode_set-->esw_offloads_start-->mlx5_eswitch_enable_sriov,我查看的代碼沒有看到地方調用。

第二種配置方法為echo switchdev > /sys/kernel/debug/mlx5/${PCI_ADDR}/compat/mode,這是后面普遍的一種配置方法,它對應的代碼路徑如下:

esw_compat_fops-->write-->esw_compat_write-->write_u16-->mlx5_devlink_eswitch_mode_set-->esw_offloads_start-->mlx5_eswitch_enable_sriov

  • mlx5_remove_dev_by_protocol首先從MLX5_INTERFACE_PROTOCOL_IB協議中移除設備
  • mlx5_add_dev_by_protocol將設備添加到協議MLX5_INTERFACE_PROTOCOL_IB中
  • esw_offloads_init初始化offload相關的一些表和repsentor端口
    • esw_create_offloads_fdb_tables創建FDB表
    • esw_create_offloads_table創建轉發表
    • esw_create_vport_rx_group創建接收組
    • esw_offloads_load_reps加載repsentor端口
  • esw_create_tsarvport的QoS管理
  • esw_enable_vport使能vport

配置OVS支持offload

配置OVS的流表offload功能的命令如下:

1
ovs-vsctl set Open_vSwitch . Other_config:hw-offload=true

utilities/ovs-vsctl.c實現我們不看了。我們主要看一下vswitchd是做了什么操作。

vswitchd/ovs-vswitchd.c

main-->bridge_run-->netdev_set_flow_api_enabled-->netdev_tc_init_flow_api主要是設置去創建或者刪除一條TC規則,如果是添加則類似/sbin/tc qdisc add dev <devname> handle ffff: ingress,如果是刪除則類似/sbin/tc qdisc del dev <devname> handle ffff: ingress

OVS offload流表下發

OVS相關部分

當報文不匹配的時候,會將報文上報,會調用udpif_upcall_handler
udpif_upcall_handler-->recv_upcalls-->handle_upcalls-->dpif_operate-->dpif_netlink_operate-->try_send_to_netdev-->parse_flow_put-->netdev_flow_put-->netdev_tc_flow_put

  • 首先判定是不是tunnel,是的話需要存儲五元組
  • 是vlan的話,記錄vid和mask
  • 記錄源目的MAC和掩碼
  • 記錄五元組及其掩碼
  • 檢測以上記錄的信息是否有不支持的,還是有挺多不支持的,具體查看函數test_key_and_mask
  • 記錄action,目前支持的是output,push_vlan,pop_vlan,set,set_mask
  • 調用tc_replace_flower將以上記錄的信息進行轉換,然后通過netlink發送給端口。

網卡驅動相關

前面ovs調用tc_replace_flower時候會觸發kernel調用函數tc_ctl_tfilter,路徑如下:

tc_ctl_tfilter-->fl_change-->fl_hw_replace_filter-->mlx5e_rep_ndo_setup_tc-->mlx5e_configure_flower-->mlx5e_tc_add_fdb_flow-->mlx5_eswitch_add_offloaded_rule

mlx5e_configure_flower

  • parse_cls_flower解析ovs傳遞過來的流表中match的key信息
  • parse_tc_fdb_actions解析ovs傳遞過來的流表中action信息
  • mlx5e_tc_add_fdb_flow主要是講match和action添加到fdb流表
  • 后面先不看了,multipath的那些操作

mlx5e_tc_add_fdb_flow

  • 如果action包含encap,那么調用mlx5e_attach_encap生成vxlan所需要的報文頭信息
  • mlx5_eswitch_add_vlan_action添加vlan的action
  • mlx5_eswitch_add_offloaded_rule添加offloaded規則

mlx5_eswitch_add_offloaded_rule-->mlx5_add_flow_rules-->_mlx5_add_flow_rules 主要是向firmware發送指令添加offload規則。

這塊關聯比較多,不太好看,以后遇到問題再去查看。

dump flows

一般是兩種命令可以展示datapath的流表,他們的區別主要是能不能dump別的datapath,主要實現都是一致的,所以我們只看一個相關的代碼,因為個人認為ovs-appctl命令更好一些,所以就看這個的代碼。

1
2
ovs-dpctl dump-flows [type=offloaded/ovs]
ovs-appctl dpctl/dump-flows [type=offloaded/ovs]

命令相關的代碼就不看了,因為ovs-appctl調用的命令都需要在ovs-vswitchd中通過函數unixctl_command_register進行注冊。我們這里直接查看注冊的dpctl相關的命令。

代碼路徑如下,文件起始於ovs-vswitchd.c

main-->bridge_run-->bridge_reconfigure-->bridge_add_ports-->bridge_add_ports__-->iface_create-->iface_do_create-->netdev_open-->construct-->dpif_create_and_open-->dpif_open-->do_open-->dp_initialize-->dpctl_unixctl_register-->dpctl_unixctl_handler-->dpctl_dump_flows

dpctl_dump_flows

  • 首先做參數檢測,保證參數合理性
  • dpif_flow_dump_create-->dpif_netlink_flow_dump_create主要有兩個事情,一個就是nl_dump_start,原來的dump ovs的流表,另一個就是dump offloaded流表,用的函數start_netdev_dump
  • 遍歷所有滿足類型條件的流表,並且根據filter進行過濾。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM