一、Open vSwitch介绍1、vSwitch功能vSwitch(Virtual Switch)指虚拟交换机或虚拟网络交换机,工作在二层数据网络,通过软件方式实现物理交换机的二层(和部分三层)网络功能。通过运行在虚拟化平台上的虚拟交换机,为本台物理机上的VM(Virtual Machine,虚拟机)提供二层网络接入和部分三层网络功能。VM通过vSwitch来连接网络,vSwitch则通过物理主机上的物理网卡作为上行链路与外界网络进行连接,如下图所示。
图1 vSwitch组网示意图
跟物理主机一样,每个VM有自己的虚拟网卡(Virtual Network Card),每个虚拟网卡有自己的MAC地址和IP地址。Port1、Port2、Port3、Port4、Port5是vSwitch上的虚拟端口vPort(Virtual Port),该虚拟交换机连接虚拟网卡和物理网卡,将虚拟机上的数据报文从物理网卡转发出去,并从物理网卡上接收报文转发给对应的虚拟网卡。根据需要,vSwitch还可以支持安全控制、VLAN、网络监控、端口镜像、QoS、自动化网管等功能。
每个vSwitch与物理交换机一样,包含一定数量的端口,相同特性的虚拟端口vPort集合就是VLAN(或称端口组),不同VLAN内的报文在传输时是相互隔离的,各VLAN内的用户不能和其它VLAN内的用户直接通信。如果不同VLAN要进行通信,则需要通过路由器、三层交换机等三层设备。
2、Open vSwitch功能及架构简单的讲,Open vSwitch 是一个用C语言开发的多层虚拟交换机,简称OvS。
复杂点讲,Open vSwitch是支持OpenFlow协议的虚拟交换机,所谓OpenFlow协议,是一套SDN控制协议,不同厂商使用该标准实现的交换机和Controller能够相互兼容,从而便于实现SDN。OvS是一个支持多层数据转发的高质量虚拟交换机,主要部署在服务器上,相比传统交换机具有很好的编程扩展性,同时具备传统交换机实现的网络隔离和数据转发功能,运行在每个实现虚拟化的物理机器上,并提供远程管理。
在传统OvS中,网卡在加载网络过程中被绑定到OvS端口上,数据包接收和发送函数在datapath中定义,因此,报文的接收和发送统一由位于内核空间的datapath进行,内核空间负责报文的解析封装、流表匹配、流表匹配失败上送、报文转发或丢弃等报文处理操作。在OvS中有两个流表,一个为位于内核空间的内核态流表,另一个是位于用户空间的用户态流表,如下图2所示。内核态流表主要是存储近期匹配过的流表项,用户态流表主要由控制器或人为通过OvS提供的ovs-ofctl工具下发。用户空间只在内核空间将报文上送用户空间时,对报文进行流表匹配操作,根据匹配结果通知内核datapath报文该如何处理,并下发匹配到的流表项至内核态流表,以备后续类似报文匹配。
OvS的功能及架构示意图如下所示,OvS包含三个基本组件:ovs-vswtichd、ovsdb-server、openvswitch.ko,各个组件的作用如下:
图2 Open vSwitch功能及架构示意图
ovs-vswitchd组件是交换机的主要模块,运行在用户态,负责OvS管理和控制的守护进程,通过 Unix Socket 将配置信息保存到ovsdb中,并通过Netlink和内核模块进行交互;其主要负责基本的转发逻辑、地址学习、外部物理端口绑定等。还可以运用OvS自带的ovs-ofctl工具采用OpenFlow协议对交换机进行远程配置和管理。
ovsdb-server组件是存储OvS的网桥配置、日志以及状态的轻量级数据库。它与ovs-vswitchd都是以一个单独的进程存在于系统中。ovsdb是一个可提供持久化存储的数据库,可借助ovs-vsctl工具配置OvS交换机,配置信息将保存在ovsdb中,设备重启后,相关OvS配置不会丢失。ovs-vswitchd组件与ovsdb-server组件间的通信采用OVSDB管理协议,通信内容包括加载配置信息,同时将运行过程中变化的OvS的配置信息保存到数据库中。
openvswitch.ko组件运行在内核态,属于快速转发平面,主要负责流表匹配、报文修改、隧道封装、转发或者上送,并且维护底层转发表。在OvS中,报文首先经过该组件完成报文解析和封装、转发规则匹配,若找到转发规则不再经过用户空间,直接转发。否则转交用户空间的ovs-vswitchd组件进行处理。ovs-vswitchd组件与openvswitch.ko组件之间采用Netlink执行进程间的通信。Netlink是一种进程间通信机制,可用于处理用户态和内核态的通信。
说明:Datapath负责数据交换的内核模块,从网口读取数据,快速匹配Flow Table中的流表项,成功直接转发,失败的上交vswitchd进程处理。在 OvS 初始化和port binding 时注册钩子函数,把端口的报文处理接管到内核模块,详细说明见后文。
同时,为了方便配置和管理OvS,提供了图2中所展示的管理工具,作用如下:
ovs-vsctl:用于获取或者更改ovs-vswitchd的配置信息,操作的时候会更新ovsdb-server中的数据库,主要用于网桥、接口等的创建、删除、设置、查询等。
查看OvS信息:ovs-vsctl show添加网桥br0:ovs-vsctl add-br br0删除网桥br0:ovs-vsctl del-br br0列出所有网桥:ovs-vsctl list-br新增internal端口p1并添加到网桥br0:ovs-vsctl add-port br0 p1 – set interface p1 type=internal添加端口p1到网桥br0:ovs-vsctl add-port br0 p1删除网桥br0上的端口p1:ovs-vsctl del-port br0 p1查看网桥br0上所有端口:ovs-vsctl list-ports br0设置端口p1的类型为patch,并与p0连接:ovs-vsctl set interface p1 type=patch options:peer=p0设置OpenFlow控制器:ovs-vsctl set-controller br0 tcp:192.168.1.20:6633(控制器地址为192.168.1.20,端口为6633)移除OpenFlow控制器:ovs-vsctl del-controller br0获取br0网桥的Openflow控制器地址,没有控制器则返回空:ovs-vsctl get-controller br0设置端口p1的vlan tag为100:ovs-vsctl set Port p1 tag=100设置端口p0类型为internal:ovs-vsctl set Interface p0 type=internal设置网桥br0的datapath_type:ovs-vsctl set bridge br0 datapath_typ=netdev查看网桥br0上端口p1的具体信息:ovs-vsctl list port p1查看网桥br0上端口p1的interface p1的具体信息:ovs-vsctl list interface p1ovs-dpctl:用于配置管理OvS的datapath,可以控制转发规则,如创建,修改和删除 datapath,一般,单个机器上的 datapath 有 256 条(0-255)。一条 datapath 对应一个虚拟网络设备。该工具还可以统计每条 datapath 上的设备通过的流量,打印流的信息等,常用命令如下所示,更过参数通过 ovs-dpctl –help 查看。
查看支持的命令:ovs-dpctl list-commands显示所有 datapath 的基本信息:ovs-dpctl show显示所有 datapath 的名字:ovs-dpctl dump-dps显示一条 datapath DP 上的流信息:ovs-dpctl dump-flows system@ovs-system查看datapath端口报文计数:ovs-dpctl show -sovs-ofctl:下发流表信息,可以用它手动配置OvS中的流表项。该命令可以配置其他openflow 交换机(采用openflow 协议)。
查看支持的命令:ovs-ofctl list-commands查看网桥br0中OpenFlow流表项(不含隐藏流):ovs-ofctl dump-flows br0查看网桥中的所有 table:ovs-ofctl dump-tables br0查看网桥br0的所有OpenFlow端口信息:ovs-ofctl show br0,ovs-ofctl dump-ports-desc br0查看网桥br0的port的统计信息:ovs-ofctl dump-ports br0添加流表项:ovs-ofctl add flow br0 in_port=vnet0,actions=normal(从vnet0端口进入的报文进行常规2、3层处理)添加流表项:ovs-ofctl add-flow br0 in_port=vnet0,actions=output:vnet1 (从vnet0端口进入的报文从vnet1端口出)添加流表项:ovs-ofctl add-flow br0 dl_dst=0e:82:42:ce:cf:0d,actions=output:vnet1 (目的mac为0e:82:42:ce:cf:0d的报文从vnet1端口出)添加流表项:ovs-ofctl add-flow br0 ip,nw_dst=192.168.1.10,actions=output:vnet1 (目的ip为192.168.1.10的报文从vnet1端口出)删除网桥br0上的所有流表项:ovs-ofctl del-flows br0删除网桥br0上入端口为vnet0的所有流表项:ovs-ofctl del-flows br0 in_port=vnet0查询网桥br0上所有的流表项的数目:ovs-ofctl dump-aggregate br0ovs-appctl:发送命令消息到ovs-vswithchd, 查看不同模块状态,例如flow、datapath、route、bond、lacp、stp等。
查看支持的命令:ovs-appctl list-commands
查看bond状态:ovs-appctl bond/show
查看所有OpenFlow流表项(包含隐藏流表项):ovs-appctl bridge/dump-flows br0
查看当前OvS中的datapath类型:ovs-appctl dpctl/dump-dps
查看默认datapath类型的接口编号:ovs-appctl dpctl/show system@ovs-system
查看datapath类型为netdev的接口编号:ovs-appctl dpctl/show netdev@ovs-netdev
查看openflow端口port number 和datapath port number:ovs-appctl dpif/show
查看datapath模块的流表项:ovs-appctl dpif/dump-flows br0
查看默认的datapath类型的OvS桥的生效流表项:ovs-appctl dpctl/dump-flows system@ovs-system
查看datapath类型为netdev的OvS桥的生效流表项:ovs-appctl dpctl/dump-flows netdev@ovs-netdev
注意:上述两条命令显示结果中的in_port(port_num)和actions:port_num,port_num值可能与使用ovs-ofctl命令查看到的不一致,这是因为使用ovs-appctl命令显示的端口号是所有datapath类型的桥下接口的编号,而ovs-ofctl命令下的端口号是此OvS桥下的端口号。
查看指定网桥上的mac地址自学习表:ovs-appctl fdb/show br0
查看datapath端口报文计数:ovs-appctl dpctl/show -s
查看lacp状态:ovs-appctl lacp/show,ovs-appctl lacp/show-stats
查看ovs路由表:ovs-appctl ovs/route/show
查看upcall信息:ovs-appctl upcall/show
查看underlay ip学习到的arp表项表:ovs-appctl tnl/arp/show,ovs-appctl tnl/neigh/show
查看CT表:ovs-appctl dpctl/dump-conntrack
ovsdb-tool:是一个专门管理OvS数据库文件的工具,不常用,它不直接与ovsdb-server进程通信。
创建并初始化database文件:ovsdb-tool create [db][schema]查看数据库更改记录:ovsdb-tool show-log -movsdb-client:是ovsdb-server进程的命令行工具,主要是从正在运行的ovsdb-server中查询信息,操作的是数据库。
列出主机上的所有数据库:ovsdb-client list-dbs列出指定数据库的所有表:ovsdb-client list-tables [DATABASE]列出指定数据库指定表的所有数据:ovsdb-client dump [DATABASE] [TABLE]监控指定数据库中的指定表记录改变:ovsdb-client monitor [DATABASE] [TABLE]获取指定数据库的schema信息:ovsdb-client get-schema [DATABASE]vtep-ctl:VTEP(VXLAN隧道端点模拟器(VXLAN Tunnel EndPoint,VTEP))配置工具。
1)工作原理前面讲述了OvS的功能和架构,接下来重点讲解一下OvS进行数据包收发处理的机制。总结如下:
接收报文处理机制当报文到达网卡设备,网卡将接收到的报文交给该网卡绑定的端口在OvS中定义的数据包接收函数处理。在datapath中首先进行报文头(源/目的 IP、源/目的 MAC、端口等)信息的获取,根据报文头信息生成匹配流表项的key值,得到key值后进行内核态流表匹配。当数据包的key值在内核态流表中匹配(通过 hash)到流表项,数据包将不经过用户空间,直接由内核进行action操作并将报文转发或丢弃。若未匹配到内核态流表项,将使用Linux系统的Netlink通信机制实现内核进程和用户进程的通信,把数据包上送到用户空间。在用户空间进行用户态流表匹配(精确流表和模糊流表)。如果模糊流表命中, ovs-vswitchd 会同时刷新用户态精确流表和内核态精确流表,如果精确流表命中,则只更新内核态流表,刷新后,重新把该数据包注入给内核态 datapath 模块处理。datapath重新发起选路,查询内核态流表,匹配;报文转发,结束。若未命中,如果还不命中,在 SDN 控制器接入的情况下,经过 OpenFlow 协议,通告给控制器,由控制器决定如何转发该数据包。发送报文处理机制OvS接收到数据包后对数据包的处理主要分为修改数据包后转发出去,向上层应用发送、丢弃三种情况。当需要将修改的数据包转发出去时,首先也是进行流表匹配,匹配过程与接收报文一致。通过命中的流表项获得要转发出去的端口号,最终将报文从OvS端口号绑定的网卡发送出去。
图3 Open vSwitch数据包收发匹配流程示意图
Open vSwitch 的数据包收发工作原理及全部匹配流程见图3。注意这里的第5步,首包上送到ovs-vswitchd 解析处理后会被再次注入到datapath中,随后查询内核态的flow table,根据查询结果进行转发处理。
2)数据包流向一般的数据包在 Linux 网络协议栈中的流向为图4中的灰色箭头流向:网卡 Physical Port0 收到数据包后判断报文走向,如果是本地报文把数据传送到用户态, 如果是转发报文根据选路(二层交换或三层路由) 把报文送到另一个网卡如 Physical Port1,数据包流向则为图4中的绿色箭头流向。
如果OvS 绑定物理网卡后(即添加物理网卡到网桥),数据包流向如图红色箭头所示:从物理网卡端口Physical Port0接收包后,在内核态由OvS的vPort进入OvS中,根据数据包Key值进行Flow Table匹配,成功则执行流表Action后续流程,失败则Upcall由vswitchd进程处理。整个数据包流向实现过程如图4所示:
图4 OvS 数据包流向
内核模块实现了多个“数据路径”(类似网桥),每个都可以有多个“vports”(类似网桥的端口)。每个数据路径也通过关联流表(flow table)来设置操作,而这些流表中的流都是用户空间在报文头和元数据的基础上映射的关键信息,一般的操作都是将数据包转发到另一个 vport。当一个数据包到达一个vport,内核模块所作的处理是提取其流的关键信息并在流表中查找这些关键信息。当有一个匹配的流时,它执行对应的操作。如果没有匹配,它会将数据包发送到用户空间的处理队列中(作为处理的一部分,用户空间可能会设置一个流用于以后碰到相同类型的数据包可以在内核中执行操作)。
二、术语解释Bridge: 网桥,即交换机(Switch),一台主机中可创建一个或多个Bridge。Bridge可根据一定的规则,把某个端口接收到的数据报文转发到另一个或多个端口上,也可以修改或者丢弃数据报文。
Port: 端口,即交换机上的插口。有以下几种类型:
Normal:将物理网卡添加到Bridge上,此时它们成为了Port,类型为Normal。此时物理网卡将不能配置IP,只负责数据报文的进出。此类型的Port常用于VLAN模式下多台物理主机相连的那个口,交换机的一端属于Trunk模式。Internal:此类型的Port,OvS会自动创建一个虚拟网卡(Interface),此端口收到的数据都转发给这块网卡,从网卡发出的数据也会通过Port交给OvS处理。当OvS创建一个新Bridge时,会自动创建一个与网桥同名的Internal Port,同时也会创建一个与网桥同名的Interface。另外,Internal Port可配置IP地址,然后将其up,即可实现OvS三层网络。Patch:与 veth pair 功能相同,可看作是一根网线,常用于连接两个Bridge。Tunnel:实现overlay网络。支持 GRE、VXLAN、STT、Geneve和IPSec等隧道协议。网卡加入网桥 IP 失效的解决办法
在 OvS 操作中常常有这么一个现象,将本机的网卡加入到网桥之中后就发现机器的 IP 地址失效了,不能 ssh,不能 ping 通。这是因为当网卡加入网桥之后,网卡就是交换机上的一个端口,交换机作为二层设备,其端口是不可能有 IP 地址的,所以本机的 IP 地址失效。这样的情况如何处理?处理方法还是有的,关键点就在网桥的一个端口。网桥创建成功后会默认带一个与网桥同名的 port,并且这个 port 的类型是比较特殊的 Internal。Internal 类型可以看做每个 OvS 交换机有个可以用来处理数据报的本地端口,可以为这个网络设备配置 IP 地址。当创建 OvS 网桥时会自带一个同名的端口,该端口就是类型为 Internal 端口。解决的思路就是 Internal 类型的 port 会生成一个虚拟网卡,将绑定到网桥的网卡的 IP 地址转移到该虚拟网卡上,然后配置路由即可。
Interface:网卡,可以是虚拟的(TUN/TAP)或物理的都可以。
Controller:控制器,OvS可接受一个或多个OpenFlow控制器的管理,主要功能为下发流表来控制转发规则。
Flow:同一时间,经过同一网络中具有某种共同特征(属性)的数据,抽象为一个流。比如,可以将访问同一目的地址的数据视为一个流;流一般由网络管理员定义,根据不同的流执行不同的策略;OpenFlow体系中,数据以“流”为单位进行处理,一般包含三种流:
OpenFlow flows:OvS中最重要的一种flows,Controller控制器下发的就是这种flows。
hidden flows:OvS在使用OpenFlow flow时,需要与OpenFlow控制器建立TCP连接,若此TCP连接不依赖OvS,即没有OvS依然可以建立连接,此时就是out-of-band control模式,这种模式下不需要”hidden” flows。 但是在in-band control模式下,TCP连接的建立依赖OvS控制的网络,但此时OvS依赖OpenFLow控制器下发的flows才能正常工作,没法建立TCP连接也就无法下发flows,这就产生矛盾了,因此需要存在一些”hidden” flows,这些”hidden” flows保证了TCP连接能够正常建立。
注意:hidden flows优先级高于OpenFlow flows,它们不需要手动设置。可以使用ovs-appctl查看这些flows,比如:输出内容包括OpenFlow flows,hidden flows:
ovs-appctl bridge/dump-flows br-namedatapath flows:datapath flows是datapath内核模块维护的flows,由内核模块维护意味着我们并不需要去修改管理它。与OpenFlow flows不同的是,它不支持优先级,并且只有一个表,这些特点使它非常适合做缓存。与OpenFlow一样的是它支持通配符,也支持指令集(多个action); datapath flows可以来自用户空间ovs-vswitchd缓存,也可以是datapath内核模块进行MAC地址学习到的flows,这取决于OvS是作为SDN交换机,还是像Linux Bridge那样只是一个简单基于MAC地址学习的二层交换机。
注意:我们可以修改和配置的是OpenFlow flows。datapath flow和”hidden” flows由OvS自身管理,我们不必去修改它。当然,调试场景下还是可以使用工具修改的。
Flow Table:流表,针对特定流的策略表项的集合,负责数据包的查找与转发。OvS进行数据转发的核心功能,定义了端口之间的转发数据报文的规则。一张流表包含了一系列的流表项(flow entries),每条流表项的规则可分为匹配和动作两部分,“匹配”决定哪些数据将被处理;动作决定了匹配到的数据报文该如何处理。
Datapath:由于流可能非常复杂,对每个进来的数据包都去尝试匹配所有流,效率会非常低,所以有了datapath这个东西。Datapath是流的一个缓存,会把流的执行结果保存起来,当下次遇到匹配到同一条流的数据包,直接通过datapath处理。考虑到转发效率,datapath完全是在内核态实现的,并且默认的超时时间非常短,大概只有3秒左右。
Datapath处理原理:用户空间ovs-vswitchd和内核模块datapath决定了数据包的转发,首先,datapath内核模块收到进入数据包(物理网卡或虚拟网卡),然后查找其缓存(datapath flows),当有一个匹配的flow时它执行对应的操作,否则datapath会把该数据包送入用户空间由ovs-vswitchd负责在其OpenFlow flows中查询(图3中的首包),ovs-vswitchd查询后把匹配的actions返回给datapath并设置一条datapath flows到datapath中,这样后续进入的同类型的数据包(图3中的后续数据包)因为缓存匹配会被datapath直接处理,不用再次进入用户空间。当ovs-vswitchd查询后生成的datapath flows在datapath中设置完毕后,首包也会被再次注入到datapath中,查询flow table后,根据结果进行转发处理。
注意:datapath专注于数据交换,它不需要知道OpenFlow的存在。与OpenFlow打交道的是ovs-vswitchd,ovs-vswitchd存储所有Flow规则供datapath查询或缓存。
Pipeline:pipeline是openflow协议中处理数据包的主体,每一个网桥有且仅有一个pipeline(也称为datapath)。网桥上无论哪种端口在pipeline看来都是openflow端口。pipeline中包含流表,openflow1.0协议只定义了一个流表,1.3+协议定义了256张流表。数据包从openflow端口进入网桥,即进入了pipeline,其处理数据包的流程是:
0)n=0,即数据包从0号流表开始,转1)。1)数据包流入n号流表,从高优先级(即priority号大)的流表项开始查找,如果匹配到转2),否则转4)。2)pipeline更新该流表项的counter等信息,执行该流表项的instruction,如果有goto或者resubmit到n号流表则转1),否则转3)。3)执行instruction中的actions,pipeline结束。4)(这种情况称为table miss)如果存在table miss表项(其实就是低优先级,match为空的流表项),则转3),否则丢弃该数据包,pipeline结束。注意:在配置流表时,如果需要对数据包进行修改,则对数据包的修改动作应该在output动作之前完成,否则会不生效(因为数据包已经发送出去)。
三、常用操作1、控制管理1)查看、创建和配置网桥# 查看网桥和端口ovs-vsctl show # 创建非dpdk接口网桥(一)ovs-vsctl add-br br0# 创建dpdk接口网桥(二)ovs-vsctl add-br br0ovs-vsctl set bridge br0 datapath_type=netdev# 罗列网桥ovs-vsctl list-br # 查看网桥所有配置信息ovs-vsctl list bridge br0# 罗列网桥下的所有端口ovs-vsctl list-ports br0 # 查看端口所属的网桥ovs-vsctl port-to-br eth1注意:OvS的datapath_type有nedev和system,即用户态和内核态,datapath一般来说是运行在内核态;在创建dpdk接口的bridge时需指定,ovs-vsctl set bridge br0 datapath_type=netdev,使用非dpdk的bridge时不需要指定,走默认的system。
2)添加/修改/删除/配置一个端口# OvS system 接口ovs-vsctl add-port br0 eth1ovs-vsctl del-port br0 eth1 # OvS DPDK接口ovs-vsctl add-port br0 dpdk1 -- set interface dpdk1 type=dpdk options:dpdk-devargs=0000:01:00.0 # OvS DPDK bonds接口ovs-vsctl add-bond br0 dpdkbond0 dpdk1 dpdk2 \ -- set interface dpdk1 type=dpdk options:dpdk-devargs=0000:01:00.0 \ -- set interface dpdk2 type=dpdk options:dpdk-devargs=0000:02:00.0 # OvS DPDK bonds接口(新版本用法)ovs-vsctl add-port br0 dpdkbond0 \ -- set interface dpdkbond0 type=dpdk options:dpdk-devargs=0000:01:00.0,0000:02:00.0 # 设置/修改OpenFlow端口号ovs-vsctl set Interface eth1 ofport_request=2# 设置端口类型ovs-vsctl add-port br0 eth1 -- set interface eth1 type=internal# 设置IP地址ip link set eth1 upip addr add 192.168.1.10/24 dev eth1# 该命令设置可以在数据库持久,也可以用来配置物理接口ovs-vsctl set interface br0 mtu_request=1450 # 该命令清除恢复到默认的MTUovs-vsctl set interface br0 mtu_request=[]3)设置/移除VLAN tag# 设置/移除允许通过的access vlan tagovs-vsctl set port eth1 tag=100ovs-vsctl remove port eth1 tag 100 # 设置VLAN mode: trunk|access|native-tagged|native-untaggedovs-vsctl set port eth1 vlan_mode=trunkovs-vsctl get port eth1 vlan_modeovs-vsctl remove port eth1 vlan_mode trunk# 设置/移除允许通过的trunk vlan tagovs-vsctl set port eth1 trunks=100,200ovs-vsctl remove port eth1 trunks 100,2004)设置Patch口ovs-vsctl add-br br0ovs-vsctl add-br br1ovs-vsctl add-port br0 patch0 -- set interface patch0 type=patch options:peer=patch1ovs-vsctl add-port br1 patch1 -- set interface patch1 type=patch options:peer=patch05)设置/清除网桥的openflow协议版本# 支持 OpenFlow Version 1.3ovs-vsctl set bridge br0 protocols=OpenFlow13# 支持 OpenFlow Version 1.0 1.1 1.2 1.3ovs-vsctl set bridge br0 protocols=OpenFlow10,OpenFlow11,OpenFlow12,OpenFlow13,OpenFlow14ovs-vsctl clear bridge br0 protocols6)查看网桥当前流表ovs-ofctl dump-flows br0ovs-ofctl -O OpenFlow13 dump-flows br0#ovs-ofctl -O OpenFlow15 dump-flows br0# 查看网桥上的OpenFlow流表数目ovs-ofctl dump-aggregate br0ovs-ofctl -O openflow15 dump-aggregate br0# 查看网桥上的table=30的OpenFlow流表数目ovs-ofctl -O openflow15 dump-aggregate br0 table=30# 查看快速路径流表ovs-appctl dpif/dump-flows br07)设置/删除/查看网桥的控制器,ovs-ofctl可以通过controller连接到网桥执行命令ovs-vsctl set-controller br0 tcp:1.2.3.4:6633ovs-vsctl del-controller br0 ovs-vsctl get-controller br08)查看控制器列表ovs-vsctl list controller9)设置/删除被动连接控制器针对ovsdb-server,一个host上只会有一个manager,ovs-vsctl/ovsdb-client可以通过manager连接到ovsdb-server。
ovs-vsctl set-manager tcp:1.2.3.4:6640ovs-vsctl get-managerovs-vsctl del-manager10)设置/移除可选选项ovs-vsctl set Interface eth1 options:link_speed=1Govs-vsctl remove Interface eth1 options link_speed11)设置Fail模式,支持 Standalone 或者 SecureOvS 交换机在连接不上控制器时有一个 fail_mode 的标志,所谓 fail_mode 就是故障模式,意思是 SDN 控制器故障时,交换机未连接控制器时的模式。
fail_mode 故障模式有两种状态,一种是 standalone,一种是 secure 状态。
如果是配置了 standalone mode,在三次探测控制器连接不成功后,此时 ovs-vswitchd 将会接管转发逻辑(后台仍然尝试连接到控制器,一旦连接则退出 fail 状态),OpenvSwitch 将作为一个正常的 mac 学习的二层交换机。
如果是配置了 secure mode,则 ovs-vswitchd 将不会自动配置新的转发流表,OpenvSwitch 将按照原先有的流表转发。
简单来说:
standalone(default):清除所有控制器下发的流表,OvS 自己接管。
secure:按照原来流表继续转发
ovs-vsctl del-fail-mode br0ovs-vsctl set-fail-mode br0 secureovs-vsctl get-fail-mode br012)查看openflow端口id和datapath端口idovs-appctl 命令用于查询和管理 ovs daemon,主要是向 ovs-vswitchd 守护进程发送命令的,查看不同模块状态。
ovs-appctl dpif/show13)查看接口统计ovs-ofctl -O openflow15 dump-ports br014)测试ovs对数据包的转发情况ovs-appctl ofproto/trace 可以测试OvS对数据包的转发情况ovs-appctl ofproto/trace br0 in_port=11,dl_src=fa:16:3e:90:1C:bc,dl_dst=0e:82:42:ce:cf:0d -generate # 查询指定ip的流表信息ovs-appctl dpctl/dump-flows -m | grep 192.168.1.1015)设置Tunnel# 本端ip:10.8.0.10, 对端ip:10.8.0.11ovs-vsctl add-br br0ovs-vsctl add-port br0 vxlan0 -- set interface vxlan0 type=vxlan options:{local_ip=10.8.0.10,remote_ip=10.8.0.11,key=100}# 本端ip:10.8.0.11, 对端ip:10.8.0.10ovs-vsctl add-br br0ovs-vsctl add-port br0 vxlan0 -- set interface vxlan0 type=vxlan options:{local_ip=10.8.0.11,remote_ip=10.8.0.10,key=100}16)其他# 查看网桥是否开启stp协议ovs-vsctl get bridge br0 stp_enable# 设置网桥开启stp协议ovs-vsctl set bridge br0 stp_enable=true# 查看port的属性ovs-vsctl list port eth1# 查看interface的属性ovs-vsctl list interface eth1# 查看网桥上所有端口的统计信息ovs-ofctl dump-ports br0# 查看ovs的版本ovs-appctl --versionovs-vsctl --version# 查看OvS支持的OpenFlow协议的版本ovs-ofctl -V开启 STP 生成树协议
STP 是 Spanning Tree Protocol 的缩写,意思是指生成树协议,可应用于计算机网络中树形拓扑结构建立,主要作用是防止网桥网络中的冗余链路形成环路工作。如图所示:
图5 STP 生成树
在上面的拓扑中,交换机之间形成环路,交换机中的广播数据包会形成广播风暴,而 STP 生成树的作用就是经过计算阻塞交换机的部分端口,使得交换机之间不会形成环路。
2、流表操作1)查看网桥的流表ovs-ofctl dump-flows br0# 查看OpenFlow流表中的所有13号流表项ovs-ofctl -O OpenFlow13 dump-flows br0 table=13# 查看所有openflow流表包含隐藏流表ovs-appctl bridge/dump-flows br0# 查看硬件卸载数据包和字节的统计信息ovs-appctl bridge/dump-flows --offload-stats br0# 查看添加到OvS datapath的所有流表,支持dump硬件卸载流ovs-appctl dpif/dump-flows br0# 查看卸载到硬件的规则或流表ovs-appctl dpctl/dump-flows type=offloaded# 查看添加到OvS datapath的所有流表,支持dump硬件卸载流,加-m选项会显示更详细的流表信息ovs-appctl dpctl/dump-flows -m2)查看网桥中端口对应的id# 查看网桥br0的所有OpenFlow端口idovs-ofctl show br0# 查看system@ovs-system类型datapath的端口idovs-appctl dpctl/show system@ovs-system# 查看netdev@ovs-netdev类型datapath的端口idovs-appctl dpctl/show netdev@ovs-netdev# 查看openflow端口id和datapath端口idovs-appctl dpif/show3)添加流表# 设置NORMAL转发ovs-ofctl add-flow br0 "priority=0 actions=NORMAL"# 添加基本端口转发的OpenFlow流表,该流表中in_port和output后接的数值为OpenFlow端口idovs-ofctl add-flow br0 "in_port=1,actions=output:2"# 添加放通arp数据包的OpenFlow流表ovs-ofctl add-flow br0 "arp,in_port=1,actions=output:2"ovs-ofctl add-flow br0 "arp,in_port=2,actions=output:1"# 添加打vlan tag的OpenFlow流表,先增加vlan tag,再转发出去ovs-ofctl add-flow br0 "in_port=1,actions=mod_vlan_vid:10,output:2" # 添加去掉vlan tag的OpenFlow流表,先去掉vlan tag, 再转发出去ovs-ofctl add-flow br0 "priority=1,in_port=1,dl_vlan=10,actions=strip_vlan,output:2"4)删除流表# 删除br0上的所有流表ovs-ofctl del-flows br0# 删除"in_port=1"的流表ovs-ofctl del-flows br0 "in_port=1"# 删除匹配条件为"priority=40001"的流表ovs-ofctl del-flows br0 "priority=40001" # 删除匹配条件为"priority=4001,ip,in_port=1,nw_src=10.1.1.10"的流表ovs-ofctl del-flows br0 "priority=4001,ip,in_port=1,nw_src=10.1.1.10" # 删除匹配条件为"priority=4001,ip,in_port=1,nw_src=10.1.1.10 action=output:2"的流表 ovs-ofctl del-flows br0 "priority=4001,ip,in_port=1,nw_src=10.1.1.10 action=output:2"5)匹配 Vlan tagvlan tag范围为0-4095。
ovs-ofctl add-flow br0 priority=401,in_port=1,dl_vlan=20,actions=output:26)匹配Vlan pcp匹配IEEE 802.1q优先代码点(PCP:Priority Code Point)优先级,指定为0~7之间的值。更高的值表示更高的帧优先级。
ovs-ofctl add-flow br0 priority=401,in_port=1,dl_vlan_pcp=7,actions=output:27)匹配源/目的MACovs-ofctl add-flow br0 in_port=1,dl_src=01:01:01:01:01:01,actions=output:2ovs-ofctl add-flow br0 in_port=2,dl_dst=01:01:01:01:01:02,actions=output:1【注意】:dl 即是 data link 的缩写。
MAC/MASK地址01:00:00:00:00:00/01:00:00:00:00:00 代表广
MAC/MASK地址00:00:00:00:00:00/01:00:00:00:00:00 代表单播
地址fe:ff:ff:ff:ff:ff匹配除多播位以外的所有位,基本上不会用到。
地址ff:ff:ff:ff:ff:ff完全匹配(等同于省略子网掩码)。
地址00:00:00:00:00:00 匹配全部位(等同于 dl_dst=*)。
8)匹配以太网类型以太网类型字段为2个字节,取值范围为0-65535。
ovs-ofctl add-flow br0 in_port=1,dl_type=0x0806,actions=output:29)匹配源/目的IP条件:指定dl_type=0x0800,或者ip。
ovs-ofctl add-flow br0 ip,in_port=1,nw_dst=20.0.0.0/24,actions=output:2ovs-ofctl add-flow br0 ip,in_port=1,nw_dst=20.0.1.0/24,actions=output:210)匹配协议号协议号字段为1个字节,取值范围为0-255,条件:指定dl_type=0x0800或者ip。
ovs-ofctl add-flow br0 ip,in_port=1,nw_proto=1,actions=output:211)匹配IP ToS/DSCPTos字段为1个字节,取值范围为0-255,DSCP字段为6个比特,取值范围为0-63。
条件:指定dl_type=0x0800/0x86dd,或者ip/ipv6,并且ToS低2位会被忽略(DSCP值为ToS的高6位,并且低2位为预留位)
ovs-ofctl add-flow br0 ip,in_port=1,nw_tos=68,actions=output:2ovs-ofctl add-flow br0 ip,in_port=1,ip_dscp=62,actions=output:212)匹配IP ecn位IP的ecn字段为2个比特,取值范围为0-3。
ovs-ofctl add-flow br0 ip,in_port=1,ip_ecn=2,actions=output:213)匹配IP TTLIP的TTL字段为1个字节,取值范围为0-255。
ovs-ofctl add-flow br0 ip,in_port=1,nw_ttl=128,actions=output:214)匹配tcp/udp,源/目的端口tcp/udp的端口为2个字节,取值范围为0-65535。
# 匹配源tcp端口179ovs-ofctl add-flow br0 tcp,tcp_src=179/0xfff0,actions=output:2# 匹配目的tcp端口179ovs-ofctl add-flow br0 tcp,tcp_dst=179/0xfff0,actions=output:2# 匹配源udp端口1234ovs-ofctl add-flow br0 udp,udp_src=1234/0xfff0,actions=output:2# 匹配目的udp端口1234ovs-ofctl add-flow br0 udp,udp_dst=1234/0xfff0,actions=output:215)匹配 tcp flagstcp flags=fin,syn,rst,psh,ack,urg,ece,cwr,ns。
ovs-ofctl add-flow br0 tcp,tcp_flags=ack,actions=output:2tcp flags的这些标志位的编号从最低有效位开始:
0:fin 查找不再有来自发送方的数据。
1:syn 同步同步序列号。
2:rst 重置连接。
3:psh 推送功能。
4:ack 确认字段有效。
5:urg 紧急指针字段有效。
6:ece ECN回显。
7:cer 减少拥塞窗口。
8:ns 现时总和
9-11:保留。
12-15:不处理,必须为零。
16)匹配icmp codeicmp code字段为1个字节,取值范围为0-255。条件:指定icmp。
ovs-ofctl add-flow br0 icmp,icmp_code=2,actions=output:217)匹配vlan TCITCI低12位为vlan id,高3位为priority,例如tci=0xf123则vlan_id为0x123和vlan_pcp=7。
ovs-ofctl add-flow br0 in_port=1,vlan_tci=0xf123,actions=output:218)匹配mpls labelmpls label字段为20比特,取值范围为0-1048575,条件:指定dl_type=0x8847/0x8848,或者mpls/mplsm。
ovs-ofctl add-flow br0 mpls,in_port=1,mpls_label=7,actions=output:219)匹配mpls tcmpls tc为3个比特,取值范围为0-7,条件:指定dl_type=0x8847/0x8848,或者mpls/mplsm。
ovs-ofctl add-flow br0 mpls,in_port=1,mpls_tc=7,actions=output:220)匹配tunnel id,源/目的IP# 匹配tunnel idovs-ofctl add-flow br0 in_port=1,tun_id=0x7/0xf,actions=output:2# 匹配tunnel源IPovs-ofctl add-flow br0 in_port=1,tun_src=192.168.1.0/255.255.255.0,actions=output:2# 匹配tunnel目的IPovs-ofctl add-flow br0 in_port=1,tun_dst=192.168.1.0/255.255.255.0,actions=output:2上述有很多协议设置了特定的数值,下表给出协议与对应数值的对应关系。
速记符匹配项ipdl_type=0x800ipv6dl_type=0x86ddicmpdl_type=0x0800,nw_proto=1icmp6dl_type=0x86dd,nw_proto=58tcpdl_type=0x0800,nw_proto=6tcp6dl_type=0x86dd,nw_proto=6udpdl_type=0x0800,nw_proto=17udp6dl_type=0x86dd,nw_proto=17sctpdl_type=0x0800,nw_proto=132sctp6dl_type=0x86dd,nw_proto=132arpdl_type=0x0806rarpdl_type=0x8035mplsdl_type=0x8847mplsmdl_type=0x88483、指令动作1)动作为出接口从指定接口将报文转发出去。
ovs-ofctl add-flow br0 in_port=1,actions=output:22)动作为groupgroup id为已创建的group table。
ovs-ofctl add-flow br0 in_port=1,actions=group:13)动作为normal转为L2/L3处理流程。
NORMAL表示L2正常交换机转发;OvS新增了NORMAL2的Action来实现L3的转发,OvS会进行MAC学习,源MAC和目的MAC的转换,源IP的转换;ovs-ofctl add-flow br0 in_port=1,actions=normalovs-ofctl add-flow br0 in_port=1,actions=NORMAL24)动作为flood从所有物理接口转发出去,除了入接口和已关闭flooding的接口。
ovs-ofctl add-flow br0 in_port=1,actions=flood5)动作为all从所有物理接口转发出去,除了入接口。
ovs-ofctl add-flow br0 in_port=1,actions=all6)动作为local一般是在与本地网桥名称相同的网络设备对应的``本地端口''上输出数据包。
ovs-ofctl add-flow br0 in_port=1,actions=local7)动作为in_port从入接口转发回去。
ovs-ofctl add-flow br0 in_port=1,actions=in_port8)动作为controller以packet-in消息上送给控制器。
ovs-ofctl add-flow br0 in_port=1,actions=controller9)动作为drop丢弃数据包操作。
ovs-ofctl add-flow br0 in_port=1,actions=drop10)动作为mod_vlan_vid修改报文的vlan id,该选项会使vlan_pcp置为0。
ovs-ofctl add-flow br0 in_port=1,actions=mod_vlan_vid:8,output:211)动作为mod_vlan_pcp修改报文的vlan优先级,该选项会使vlan_id置为0。
ovs-ofctl add-flow br0 in_port=1,actions=mod_vlan_pcp:7,output:212)动作为strip_vlan剥掉报文内外层vlan tag。
ovs-ofctl add-flow br0 in_port=1,actions=strip_vlan,output:213)动作为pop_vlan弹出报文最外层vlan tag。
ovs-ofctl add-flow br0 in_port=1,dl_type=0x8100,dl_vlan=777,actions=pop_vlan,output:214)动作为push_vlan在报文外层压入一层vlan tag,需要使用openflow1.1以上版本兼容。
ovs-ofctl add-flow -O OpenFlow13 br0 in_port=1,actions=push_vlan:0x8100,set_field:4097->vlan_vid,output:2ps: set field值为4096+vlan_id,并且vlan优先级为0,即4096-8191,对应的vlan_id为0-4095。
15)动作为push_mpls修改报文的ethertype,并且压入一个MPLS LSE。
ovs-ofctl add-flow br0 in_port=1,actions=push_mpls:0x8847,set_field:10->mpls_label,output:216)动作为pop_mpls剥掉最外层mpls标签,并且修改ethertype为非mpls类型。
ovs-ofctl add-flow br0 mpls,in_port=1,mpls_label=20,actions=pop_mpls:0x0800,output:217)动作为修改源/目的MAC,修改源/目的IP# 修改源MACovs-ofctl add-flow br0 in_port=1,actions=mod_dl_src:00:00:00:00:00:01,output:2# 修改目的MACovs-ofctl add-flow br0 in_port=1,actions=mod_dl_dst:00:00:00:00:00:01,output:2# 修改源IPovs-ofctl add-flow br0 in_port=1,actions=mod_nw_src:192.168.1.1,output:2# 修改目的IPovs-ofctl add-flow br0 in_port=1,actions=mod_nw_dst:192.168.1.1,output:218)动作为修改TCP/UDP/SCTP源目的端口# 修改TCP源端口ovs-ofctl add-flow br0 tcp,in_port=1,actions=mod_tp_src:67,output:2# 修改TCP目的端口ovs-ofctl add-flow br0 tcp,in_port=1,actions=mod_tp_dst:68,output:2# 修改UDP源端口ovs-ofctl add-flow br0 udp,in_port=1,actions=mod_tp_src:67,output:2# 修改UDP目的端口ovs-ofctl add-flow br0 udp,in_port=1,actions=mod_tp_dst:68,output:219)动作为mod_nw_tos修改ToS字段的高6位,范围为0-255,值必须为4的倍数,并且不会去修改ToS低2位ecn值;条件:指定dl_type=0x0800。
ovs-ofctl add-flow br0 ip,in_port=1,actions=mod_nw_tos:68,output:220)动作为mod_nw_ecn修改ToS字段的低2位,范围为0-3,并且不会去修改ToS高6位的DSCP值;条件:指定dl_type=0x0800,需要使用openflow1.1以上版本兼容。
ovs-ofctl add-flow br0 ip,in_port=1,actions=mod_nw_ecn:2,output:221)动作为mod_nw_ttl修改IP报文ttl值,需要使用openflow1.1以上版本兼容。
ovs-ofctl add-flow -O OpenFlow13 br0 in_port=1,actions=mod_nw_ttl:6,output:222)动作为dec_ttl对IP报文进行ttl自减操作。
ovs-ofctl add-flow br0 in_port=1,actions=dec_ttl,output:223)动作为set_mpls_label对报文最外层mpls标签进行修改,范围为20bit值。
ovs-ofctl add-flow br0 in_port=1,actions=set_mpls_label:666,output:224)动作为set_mpls_tc对报文最外层mpls tc进行修改,范围为0-7。
ovs-ofctl add-flow br0 in_port=1,actions=set_mpls_tc:7,output:225)动作为set_mpls_ttl对报文最外层mpls ttl进行修改,范围为0-255。
ovs-ofctl add-flow br0 in_port=1,actions=set_mpls_ttl:255,output:226)动作为dec_mpls_ttl对报文最外层mpls ttl进行自减操作。
ovs-ofctl add-flow br0 in_port=1,actions=dec_mpls_ttl,output:227)动作为move NXM字段使用move参数对NXM字段进行操作。
# 将报文源MAC复制到目的MAC字段,并且将源MAC改为00:00:00:00:00:01ovs-ofctl add-flow br0 in_port=1,actions=move:NXM_OF_ETH_SRC[]->NXM_OF_ETH_DST[],mod_dl_sr:00:00:00:00:00:01,output:2ps: 常用NXM字段参照表
NXM字段报文字段NXM_OF_ETH_SRC源MACNXM_OF_ETH_DST目的MACNXM_OF_ETH_TYPE以太网类型NXM_OF_VLAN_TCIvidNXM_OF_IP_PROTOIP协议号NXM_OF_IP_TOSIP ToS值NXM_NX_IP_ECNIP ToS ECNNXM_OF_IP_SRC源IPNXM_OF_IP_DST目的IPNXM_OF_TCP_SRCTCP源端口NXM_OF_TCP_DSTTCP目的端口NXM_OF_UDP_SRCUDP源端口NXM_OF_UDP_DSTUDP目的端口NXM_OF_SCTP_SRCSCTP源端口NXM_OF_SCTP_DSTSCTP目的端口28)动作为load NXM字段使用load参数对NXM字段进行赋值操作。
# push mpls label,并且把10(0xa)赋值给mpls labelovs-ofctl add-flow br0 in_port=1,actions=push_mpls:0x8847,load:0xa->OXM_OF_MPLS_LABEL[],output:2# 对目的MAC进行赋值ovs-ofctl add-flow br0 in_port=1,actions=load:0x001122334455->OXM_OF_ETH_DST[],output:24、meter表由于meter表是openflow1.3版本以后才支持,所以所有命令需要指定OpenFlow1.3版本以上。
注意:在openvswitch v2.8之前的版本中,还不支持meter;在v2.8版本之后已经实现,要正常使用的话,需要注意的是datapath类型要指定为netdev,band type暂时只支持drop,还不支持DSCP REMARK。
1)查看当前设备对meter的支持ovs-ofctl -O OpenFlow13 meter-features br02)查看meter表ovs-ofctl -O OpenFlow13 dump-meters br03)查看meter统计ovs-ofctl -O OpenFlow13 meter-stats br04)创建meter表# 限速类型以kbps(kilobits per second)计算,超过20kb/s则丢弃ovs-ofctl -O OpenFlow13 add-meter br0 meter=1,kbps,band=type=drop,rate=20# 同上,增加burst size参数ovs-ofctl -O OpenFlow13 add-meter br0 meter=2,kbps,burst,band=type=drop,rate=20,burst_size=256# 同上,增加stats参数,对meter进行计数统计ovs-ofctl -O OpenFlow13 add-meter br0 meter=3,kbps,burst,stats,band=type=drop,rate=20,burst_size=256# 限速类型以pktps(packets per second)计算,超过1000pkt/s则丢弃ovs-ofctl -O OpenFlow13 add-meter br0 meter=4,pktps,band=type=drop,rate=10005)删除meter表# 删除全部meter表ovs-ofctl -O OpenFlow13 del-meters br0# 删除meter id=1ovs-ofctl -O OpenFlow13 del-meter br0 meter=16)创建流表并绑定meterovs-ofctl -O OpenFlow13 add-flow br0 in_port=1,actions=meter:1,output:25、group表由于group表是openflow1.1版本以后才支持,所以所有命令需要指定OpenFlow1.1版本以上。
【拓展:group表的能力】
节省流表空间:组表的能力可以存储多个动作,当匹配到一个合适的动作后可以执行多个动作,优化了流表一个匹配+一个动作的工作模式。
数据包复制:组表可以将进入的流量复制成多份,并对每一份单独处理。特定场合下如流量分析,可以一边将流量正常转发,一边将流量导入到某一个分析机中。
容错能力(备用端口/路径):组表有识别up端口和down端口的能力,可以在up的端口down掉之后将选择一个新的up端口转发流量。 例如:如果一个数据包应该在端口1离开交换机,但是这个端口down掉了,你想要将数据包通过端口2发送出去。如果用流表的话,当端口1down掉,需要找到所有含有“发往端口1”的流表项,全部修改成端口2,这个操作是很复杂的。这个时候,需要定义一个“1st live” group来表示这种容错行为,然后将所有的流表项的规则指向该组表。只要端口1正常,group会把所有的数据包发往端口1,如果端口1 down掉,将所有数据包发往端口2,流表没有任何变化。
负载分流:组表可以选择动作中的某一个动作执行,在负载的场景下就可以通过转发到不同的端口实现后端流量负载。
group table支持4种类型:
all:执行组表中所有的动作。这种类型通常被用在组播或者广播转发。数据包非常高效的复制给每一个桶。每一个数据都被组表中的动作桶执行。如果一个动作是直接将数据包转发到进入的端口,这个包的复制会被放弃。如果控制器中写入了转发到进端口的流表,组表必须包含一个转发动作为OFPT_IN_PORT的保留动作。select: 执行组表中的一个动作桶。数据包被组表中一个桶处理,具体是哪一个动作通取决于交换机的选择算法,常用于负载均衡。所有关于选择算法的配置和状态都是独立于OpenFlow协议之外的。ff(FAST FAILOVER):执行第一个活动的桶。每个动作桶和特殊的端口或组表有关系,可以控制动作桶的存活。动作桶有序的定义在组表中,第一个和活动的端口有关系的桶会被选择。这种类型可以修改交换机的流表而不需要控制器下发流表。如果没有动作桶是活动的,数据包会被丢弃。indirect:执行组表中的一个动作桶。这种组表只支持一个动作桶。允许多个流表条目或者组表指向这个id,支持更快,更高校的聚合。这种组类型是所有组类型中最高效的方式。1)查看当前设备对group的支持ovs-ofctl -O OpenFlow13 dump-group-features br02)查看group表ovs-ofctl -O OpenFlow13 dump-groups br03)创建group表# 类型为allovs-ofctl -O OpenFlow13 add-group br0 group_id=1,type=all,bucket=output:1,bucket=output:2,bucket=output:3# 类型为selectovs-ofctl -O OpenFlow13 add-group br0 group_id=2,type=select,bucket=output:1,bucket=output:2,bucket=output:3# 类型为select,指定hash方法(5元组,OpenFlow1.5+)ovs-ofctl -O OpenFlow15 add-group br0 group_id=3,type=select,selection_method=hash,fields=ip_src,bucket=output:2,bucket=output:34)删除group表ovs-ofctl -O OpenFlow13 del-groups br0 group_id=25)创建流表并绑定组表ovs-ofctl -O OpenFlow13 add-flow br0 in_port=1,actions=group:26、goto table配置数据包都是从table0开始匹配的,如果table0中的flow是空的时候,则数据包被丢弃。如果处理数据包的flow在非0的table中,需要给table0中添加一条将数据包发送给指定的table的flow。
数据流先从table0开始匹配,如actions有goto_table,再进行后续table的匹配,实现多级流水线,如需使用goto table,则创建流表时,指定table id,范围为0-255,不指定则默认为table0。
1)在table1中添加两条流表条目# 首先清空流表ovs-ofctl del-flows br0# 添加如下的流表,无法通信ovs-ofctl add-flow br0 "table=1, priority=1,in_port=1,actions=output:2"ovs-ofctl add-flow br0 "table=1, priority=1,in_port=2,actions=output:1"2)在table0中添加一条流表条目# 现在给table0加上一条将数据包发送到table1处理的flow,这样就可以实现通信了ovs-ofctl add-flow br0 "table=0, actions=goto_table=1"7、Tunnel配置如需配置tunnel,必需确保当前系统对各tunnel的remote ip网络可达,即物理上连通。
1)GRE(1)创建一个gre接口,并且指定端口id=1001。ovs-vsctl add-port br0 gre0 -- set Interface gre0 type=gre options:{local_ip=1.1.1.2,remote_ip=1.1.1.1,ofport_request=1001}(2)可选选项将tos或者ttl在隧道上继承,并将tunnel id设置成123。
ovs-vsctl set Interface gre0 options:tos=inherit options:ttl=inherit options:key=123(3)创建关于gre流表# 封装gre转发ovs-ofctl add-flow br0 ip,in_port=1,nw_dst=10.10.0.0/16,actions=output:1001# 解封gre转发ovs-ofctl add-flow br0 in_port=1001,actions=output:12)VXLAN(1)创建一个vxlan接口,并且指定端口id=2001ovs-vsctl add-port br0 vxlan0 -- set Interface vxlan0 type=vxlan options:{local_ip=1.1.1.2,remote_ip=1.1.1.1,ofport_request=2001}(2)可选选项将tos或者ttl在隧道上继承,将vni设置成123,UDP目的端为设置成8472(默认为4789)。
ovs-vsctl set Interface vxlan0 options:tos=inherit options:ttl=inherit options:key=123 options:dst_port=8472(3)创建关于vxlan流表# 封装vxlan转发ovs-ofctl add-flow br0 ip,in_port=1,nw_dst=10.10.0.0/16,actions=output:2001# 解封vxlan转发ovs-ofctl add-flow br0 in_port=2001,actions=output:18、QoS配置Open vSwitch本身不实现QoS,它使用Linux内核自带的traffic-control机制进行流量控制。主要两种实现方式:
Policing管制:Policing用于控制接口上接收分组(ingress)的速率,是一种简单的QoS的功能,通过简单的丢包机制实现接口速率的限制,它既可以作用于物理接口,也可以作用于虚拟接口。Shaping整形:Shaping是作用于接口上的出口流量(egress)策略,可以实现QoS队列,不同队列里面处理不同策略。policing在OvS中采用ingress_policing_rate和ingress_policing_burst两个字段完成ingress入口限速功能,该两个字段放在Interface表中。
shaping用于实现出口流量的控制,使用了队列queue,可以缓存和调度数据包发送顺序,比policing更加精确和有效,在OvS的数据表中主要使用QoS和Queue两张表。
1)ingress policing(1)配置ingress policing,对接口eth0入流限速10Mbps入口限速直接配置在网络接口上,如下所示:
ovs-vsctl set interface eth0 ingress_policing_rate=10000ovs-vsctl set interface eth0 ingress_policing_burst=1500【解析】
eth0:加入OvS桥端口的网络接口名称;ingress_policing_rate:为接口最大收包速率,单位kbps,超过该速度的报文将被丢弃,默认值为0表示关闭该功能;ingress_policing_burst:为最大突发流量大小,单位kb。默认值0表示1000kb,这个参数最小值应不小于接口的MTU,通常设置为ingress_policing_rate的10%更有利于tcp实现全速率;(2)清除相应接口的ingress policer配置ovs-vsctl set interface eth0 ingress_policing_rate=0ovs-vsctl set interface eth0 ingress_policing_burst=0(3)查看接口ingress policer配置ovs-vsctl list interface eth0(4)查看网桥支持的Qos类型ovs-appctl qos/show-types br02)egress shaping(1)QoS创建命令ovs-vsctl set port eth0 qos=@newqos -- --id=@newqos create qos type=linux-htb queues=0=@q0 -- --id=@q0 create queue other-config:max-rate=100000000注意:上面”--”用于把命令分割成单独解析的命令行。
创建Queue
创建q0队列,设置最大速率100M。
--id=@q0 create queue other-config:max-rate=100000000创建Qos规则
创建qos规则newqos,类型为linux-htb,并连接key值为0的队列q0。
--id=@newqos create qos type=linux-htb queues=0=@q0创建接口QoS
设置接口eth0的qos为newqos。
set port eth0 qos=@newqos(2)查看配置的port表ovs-vsctl list port(3)查看配置的Qos表ovs-vsctl list qos(4)查看配置的Queue表ovs-vsctl list queue9、sflow配置1)对网桥br0进行sflow监控agent: 与collector通信所在的网口名,通常为管理口target: collector监听的IP地址和端口,端口默认为6343header: sFlow在采样时截取报文头的长度polling: 采样时间间隔,单位为秒ovs-vsctl -- --id=@sflow create sflow agent=eth0 target=\"10.0.0.1:6343\" header=128 sampling=64 polling=10 -- set bridge br0 sflow=@sflow2)查看创建的sflowovs-vsctl list sflow3)删除对应的网桥sflow配置,参数为sFlow UUIDovs-vsctl remove bridge br0 sflow 7b9b962e-fe09-407c-b224-5d37d9c1f2b34)删除网桥下所有sflow配置ovs-vsctl -- clear bridge br0 sflow10、端口镜像配置1)配置eth0收到/发送的数据包镜像到eth1ovs-vsctl -- set bridge br0 mirrors=@m \-- --id=@eth0 get port eth0 \-- --id=@eth1 get port eth1 \-- --id=@m create mirror name=mymirror select-dst-port=@eth0 select-src-port=@eth0 output-port=@eth12)删除端口镜像配置ovs-vsctl -- --id=@m get mirror mymirror -- remove bridge br0 mirrors @m3)清除网桥下所有端口镜像配置ovs-vsctl clear bridge br0 mirrors4)查看端口镜像配置ovs-vsctl get bridge br0 mirrors11、聚合口配置1)创建一个聚合口ovs-vsctl add-port br0 dpdkbond0 \-- set interface dpdkbond0 type=dpdk options:dpdk-devargs=0000:01:00.0,0000:02:00.02)设置聚合口模式# mode=1ovs-vsctl set port dpdkbond0 bond_mode=active-backup # mode=2ovs-vsctl set port dpdkbond0 bond_mode=balance-slb # mode=4ovs-vsctl set port dpdkbond0 bond_mode=balance-tcpovs-vsctl set port dpdkbond0 lacp=activeovs-vsctl set port dpdkbond0 lacp=offovs-vsctl set port dpdkbond0 lacp=passive3)查看mode=4 lacp协商状态ovs-appctl lacp/show