vieyahn2017 / iBlog

44 stars 0 forks source link

openvswitch学习 #401

Open vieyahn2017 opened 3 months ago

vieyahn2017 commented 3 months ago

openvswitch

vieyahn2017 commented 3 months ago

OpenvSwitch基础

1、命令参考手册:http://www.openvswitch.org//support/dist-docs/index.html

2、openvswitch分为OVSDB和VSwitchD两个服务, OVSDB主要记录接口、设备、控制器等信息,这些都是重启openvswitch服务后可以恢复的 VSwitchD主要增删流表、转发数据,这些都是重启openvswitch服务后不能恢复的

ps -Af | grep ovs 可以看到 ovsdb-server 和 ovs-vswitchd

3、ovs-vsctl 命令 用于查询接口、设备、控制器信息, 内部实现是用JSON协议与OVSDB服务通信,

查看接口信息命令 ovs-vsctl list Interface tap050101fe-70

查看端口信息命令 ovs-vsctl list Port tap050101fe-70

4、ovs-ofctl 命令 用于查看流表信息, 内部实现是用OpenFlow协议与VSwitchD服务通信,

查看流表命令 ovs-ofctl dump-flows br-int

修改流表命令 ovs-ofctl add-flow br-int "..." ovs-ofctl mod-flows br-int "..." ovs-ofctl del-flows br-int "..."

5、ovs-appctl 命令 用于查看VSwitchD的高级信息, 内部实现是用JSON协议与VSwitchD服务通信, 功能包括且不限于bond控制,精确流表,路径追踪,路由配置,ARP配置,日志等级 这些大多数专用于DPDK场景,新手不建议使用。

vieyahn2017 commented 3 months ago

Linux下标准OVS原理与实现

OVS是openvswitch的简称,它是在linux网桥基础上发展起来的,符合openflow协议的软件交换机,兼备普通二层交换和基于流转发功能。

OVS在实现中分为用户空间和内核空间两个部分。其中,OVS在用户空间程序拥有多个组件,它们主要负责用于实现数据交换和OpenFlow流表功能,是OVS的核心。同时,OVS还提供了一些工具用于交换机管理、数据库搭建,以及和内核组件的交互。OVS的核心组件及其关联关系如图所示。 如图所示,OVS中最重要的组件是ovs-vswitchd,它实现了OpenFlow交换机的核心功能,并且通过netlink协议直接和OVS的内核模块进行通信。交换机运行过程中,ovs-vswitchd还会将交换机的配置、数据流信息及其变化保存到数据库ovsdb中,因为这个数据库由ovsdb-server直接管理,所以ovs-vswitchd需要和ovsdb-server通过UNIX socket机制进行通信以获得或者保存配置信息。数据库ovsdb的存在,使得OVS交换机的配置能够被持久化存储,即便设备被重启后相关的OVS配置仍旧能够存在。

ovs-vsctl组件是一个用于交换机管理的基本工具,它需要直接和ovs-vswitchd通信,能够支持很多管理操作,用户可以登录到交换机部署的服务器上通过ovs-vsctl管理OVS交换机。同时,ovs-appctl组件也是一个管理工具,通过发送一些内部命令给ovs-vswitchd组件以改变其配置。另外,在一些情况下,用户可能会需要自行管理运行在内核中的数据通路,那么也可以通过调用ovs-dpctl驱使ovs-vswitchd在不依赖于数据库的情况下去管理内核空间中的数据通路。

当用户需要和ovsdb-server通信以进行一些数据库操作时,可以通过运行ovsdb-client组件访问ovsdb-server,或者直接使用ovsdb-tool而不经ovsdb-server就对ovsdb数据库进行操作。

对于支持OpenFlow的OVS而言,支持集中部署的控制器对其进行远程管理和监控,才是它所体现出的软件定义网络的核心。在OVS实现中,OpenFlow是用于管理交换机流表的协议。通过使用ovs-ofctl,用户可以使用OpenFlow去连接交换机并在远程开展监控和管理。另外,OVS还提供了sFlow协议用于数据包的采样和监控,可以通过额外的sFlowTrend等软件(未包含在OVS软件包中)驱动该协议。

如前文所述,OVS在数据包的转发中拥有一条基于内核模块的快速通道,那么用户空间和内核空间是怎么通信的呢?这主要是依赖了netlink协议(Linux系统中用户空间与内核空间进行数据交换的一种方式,OVS使用的是generic netlink)。OVS在其内核空间中定义了几组genl命令,用于get/set/add/delete相应的datapath/flow/vport以及针对特定的数据包执行一些动作。其中,datapath/flow/vport都是OVS对网络资源进行的抽象描述。

OVS交换机负责数据流发送的相关流程如下。

(1)OVS定义的port结构在内核态观察到从OVS上链接的某块虚拟网卡上有数据包发来时,将其传递给一个名为internal_dev_xmit()的函数,该函数会依次接收数据包。

(2)OVS在内核状态下查看流表结构,观察是否有缓存的信息可用于转发这个数据包,这项工作主要是由ovs_flow_tbl_lookup()函数完成。该函数的运行需要一个key值,key值将从ovs_flow_extract()函数通过收集数据包的L2~L4层的细节信息中得到,然后为相应的流构建一个独一无二的key值。

(3)假设数据包是从虚拟网卡上发出的第一个包,那么在OVS内核中将不会有相应的流表缓存存在,那么内核将不会知道如何处置这个数据包。这时,内核就会通过genl(generic netlink)发送一个upcall给用户空间。

(4)位于OVS用户空间的ovs-vswitchd进程在接收到upcall后,将检查数据库以查看数据包的目的端口是哪里,然后通过OVS_ACTION_ATTR_OUTPUT告诉内核应该将数据包转发到哪个端口,例如eth0。

(5)最终,OVS_PACKET_CMD_EXECUTE命令将使得内核执行用户此前设置的动作。即内核将在do_execute_actions()函数中执行这条genl命令,并将数据包通过do_output()函数转发给端口eth0,进而数据包将被发出。

OVS在接收数据包时与上述流程类似,OVS会利用netdev_frame_hook()函数为每个与外部相连的设备注册一个rx_handler。因此,一旦这些设备在线上接收到了数据包,那么OVS将把它转发到用户空间并检查它应该发往何处及应该对其采用何种动作。例如,如果这是一个VLAN数据包,那么VLAN tag就需要首先从数据包中被去除,然后再将其转发到正确的端口。

vieyahn2017 commented 3 months ago

openvswitch源码解析-flow流表查询

OVS当前版本采用Megaflow+Microflow Cache的流表组织形式。Microflow Cache作为一级Cache,该Cache指向最近匹配的Megaflow Cache表项。当报文进入流表匹配流程后,首先根据skb_hash在Microflow Cache中查找,获取mask_index,然后获取相应sw_flow_mask;最后根据该sw_flow_mask获取相应flow。如果上述流程没有匹配,则遍历整个mask_array,做全量查找。

数据结构

匹配流程: 流表查询由ovs_flow_tbl_lookup_stats完成 1、根据skb_hash,在tbl->mask_cache中查找cache entry,如果查到,已tbl->mask_cache[index]->mask_index传入flow_lookup进行流表查找;否则将skb_hash右移MC_HASH_SHIFT继续查找;如果在MC_HASH_SEGS次没有查到相应流表,则调用flow_lookup进行全量查找; 2、根据mask_index,获取mask_array中缓存的sw_flow_mask,如果获取到,则已此sw_flow_mask传入masked_flow_lookup查找流表;否则,遍历所有mask_array; 3、计算maskd_key,hash;然后调用find_bucket获取sw_flow head指针;最后遍历sw_flow链表获取相应flow

源码分析

1、ovs_flow_tbl_lookup_stats

  1. flow_lookup 3.masked_flow_lookup