目录
文章目录
- QoS
版本
# 查看 OvS 版本
$ ovs-appctl --version
ovs-appctl (Open vSwitch) 2.0.0
Compiled Apr 19 2018 17:57:34
# 查看 OvS 支持的 OpenFlow 版本
$ ovs-ofctl --version
ovs-ofctl (Open vSwitch) 2.0.0
Compiled Apr 19 2018 17:57:34
OpenFlow versions 0x1:0x4
日志
# 查看 OvS Log 级别
$ ovs-appctl vlog/list
# 设置 Log 级别
#ovs-appctl vlog/set {module name}:{console, syslog, file}:{off, emer, err, warn, info, dbg}
$ ovs-appctl vlog/set stp:file:dbg
# 查询指令历史记录
$ ovsdb-tool show-log [-mmm]
控制管理类
# 设置/清除网桥的 OpenFlow 协议版本
ovs-vsctl set bridge br0 protocols=OpenFlow13
ovs-vsctl clear bridge br0 protocols
# 设置/删除控制器
ovs-vsctl set-controller br0 tcp:1.2.3.4:6633
ovs-vsctl del-controller br0
# 查看控制器列表
ovs-vsctl list controller
# 设置/删除被动连接控制器
ovs-vsctl set-manager tcp:1.2.3.4:6640
ovs-vsctl get-manager
ovs-vsctl del-manager
# 设置 Fail 模式,支持 Standalone 或者 Secure。
# - standalone(default):清除所有控制器下发的流表,OvS 自己接管。
# - secure:按照原来流表继续转发。
ovs-vsctl del-fail-mode br0
ovs-vsctl set-fail-mode br0 secure
ovs-vsctl get-fail-mode br0
# 设置/移除可选选项
ovs-vsctl set Interface eth0 options:link_speed=1G
ovs-vsctl remove Interface eth0 options link_speed
虚拟网桥类
# 查看网桥和端口
ovs-vsctl show
# 创建一个网桥
ovs-vsctl add-br br0
ovs-vsctl set bridge br0 datapath_type=netdev
# 添加/删除一个端口
# for system interfaces
ovs-vsctl add-port br0 eth1
ovs-vsctl del-port br0 eth1
# for DPDK
ovs-vsctl add-port br0 dpdk1 -- set interface dpdk1 type=dpdk options:dpdk-devargs=0000:01:00.0
# for 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
# or new version
ovs-vsctl add-port br0 dpdkbond0 \
-- set interface dpdkbond0 type=dpdk options:dpdk-devargs=0000:01:00.0,0000:02:00.0
# 查看某网桥当前流表
ovs-ofctl dump-flows br0
ovs-ofctl -O OpenFlow13 dump-flows br0
ovs-appctl bridge/dump-flows br0
# 查看 Interface ID 等
ovs-appctl dpif/show
# 查看接口统计
ovs-ofctl dump-ports br0
VLAN
# 添加 VLAN tag
ovs-ofctl add-flow s1 "in_port=1,actions=mod_vlan_vid:10,output:2"
# 去掉 VLAN tag 再匹配转发
ovs-ofctl add-flow s1 "priority=1,in_port=1,dl_vlan=10,actions=strip_vlan,output:2"
# 按照 VLAN tag 去匹配转发,范围为 0-4095
ovs-ofctl add-flow s1 "priority=1,in_port=1,dl_vlan=777,actions=output:2"
# 按照 VLAN pcp 去匹配转发
ovs-ofctl add-flow s1 "priority=1,in_port=1,dl_vlan_pcp=7,actions=output:2"
流表类
表项
# 添加普通流表
ovs-ofctl add-flow br0 in_port=1,actions=output:2
# 按匹配项来删除流表
ovs-ofctl del-flows br0 "in_port=1"
# 删除所有流表
ovs-ofctl del-flows br0
匹配
# 匹配 VLAN tag,范围为 0-4095
ovs-ofctl add-flow br0 priority=401,in_port=1,dl_vlan=777,actions=output:2
# 匹配 VLAN pcp,范围为 0-7
ovs-ofctl add-flow br0 priority=401,in_port=1,dl_vlan_pcp=7,actions=output:2
# 匹配源/目的 MAC
ovs-ofctl add-flow br0 in_port=1,dl_src=00:00:00:00:00:01/00:00:00:00:00:01,actions=output:2
ovs-ofctl add-flow br0 in_port=1,dl_dst=00:00:00:00:00:01/00:00:00:00:00:01,actions=output:2
# 匹配以太网类型,范围为 0-65535
ovs-ofctl add-flow br0 in_port=1,dl_type=0x0806,actions=output:2
# 匹配源/目的 IP
# 条件:指定 dl_type=0x0800,或者 ip/tcp
ovs-ofctl add-flow br0 ip,in_port=1,nw_src=10.10.0.0/16,actions=output:2
ovs-ofctl add-flow br0 ip,in_port=1,nw_dst=10.20.0.0/16,actions=output:2
# 匹配协议号,范围为 0-255
# 条件:指定 dl_type=0x0800 或者 ip
# ICMP
ovs-ofctl add-flow br0 ip,in_port=1,nw_proto=1,actions=output:2
# 匹配 IP ToS/DSCP,ToS 范围为 0-255,DSCP 范围为 0-63
# 条件:指定 dl_type=0x0800/0x86dd,并且 ToS 低 2 位会被忽略,DSCP 值为 ToS 的高 6 位,并且低 2 位为预留位。
ovs-ofctl add-flow br0 ip,in_port=1,nw_tos=68,actions=output:2
ovs-ofctl add-flow br0 ip,in_port=1,ip_dscp=62,actions=output:2
# 匹配 IP ECN 位,范围为 0-3
# 条件:指定 dl_type=0x0800/0x86dd
ovs-ofctl add-flow br0 ip,in_port=1,ip_ecn=2,actions=output:2
# 匹配 IP TTL,范围为 0-255
ovs-ofctl add-flow br0 ip,in_port=1,nw_ttl=128,actions=output:2
# 匹配 tcp/udp,源/目的端口,范围为 0-65535
# 匹配源 tcp 端口 179
ovs-ofctl add-flow br0 tcp,tcp_src=179/0xfff0,actions=output:2
# 匹配目的 tcp 端口 179
ovs-ofctl add-flow br0 tcp,tcp_dst=179/0xfff0,actions=output:2
# 匹配源 udp 端口 1234
ovs-ofctl add-flow br0 udp,udp_src=1234/0xfff0,actions=output:2
# 匹配目的 udp 端口 1234
ovs-ofctl add-flow br0 udp,udp_dst=1234/0xfff0,actions=output:2
# 匹配 tcp flags
# tcp flags=fin,syn,rst,psh,ack,urg,ece,cwr,ns
ovs-ofctl add-flow br0 tcp,tcp_flags=ack,actions=output:2
# 匹配 icmp code,范围为 0-255
# 条件:指定 icmp
ovs-ofctl add-flow br0 icmp,icmp_code=2,actions=output:2
# 匹配 VLAN TCI
# TCI 低 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:2
# 匹配 MPLS label
# 条件:指定 dl_type=0x8847/0x8848
ovs-ofctl add-flow br0 mpls,in_port=1,mpls_label=7,actions=output:2
# 匹配 MPLS tc,范围为 0-7
# 条件:指定 dl_type=0x8847/0x8848
ovs-ofctl add-flow br0 mpls,in_port=1,mpls_tc=7,actions=output:2
# 匹配 Tunnel id,源/目的 IP
# 匹配 tunnel id
ovs-ofctl add-flow br0 in_port=1,tun_id=0x7/0xf,actions=output:2
# 匹配 tunnel 源 IP
ovs-ofctl add-flow br0 in_port=1,tun_src=192.168.1.0/255.255.255.0,actions=output:2
# 匹配 tunnel 目的 IP
ovs-ofctl add-flow br0 in_port=1,tun_dst=192.168.1.0/255.255.255.0,actions=output:2
动作
# normal,标准的 L2/L3 处理流程。
ovs-ofctl add-flow br0 in_port=1,actions=normal
# output,从指定接口转发出去。
ovs-ofctl add-flow br0 in_port=1,actions=output:2
# flood,从所有物理接口转发出去(除了入接口和已关闭 flooding 的接口)。
ovs-ofctl add-flow br0 in_port=1,actions=flood
# all,从所有物理接口转发出去(除了入接口)。
ovs-ofctl add-flow br0 in_port=1,actions=all
# local,转发给本地网桥。
ovs-ofctl add-flow br0 in_port=1,actions=local
# in_port,从入接口转发回去。
ovs-ofctl add-flow br0 in_port=1,actions=in_port
# controller,以 packet-in 消息上送给控制器。
ovs-ofctl add-flow br0 in_port=1,actions=controller
# drop,丢弃数据包操作。
ovs-ofctl add-flow br0 in_port=1,actions=drop
# mod_vlan_vid,修改报文的 VLAN id,该选项会使 vlan_pcp 置为 0。
ovs-ofctl add-flow br0 in_port=1,actions=mod_vlan_vid:8,output:2
# mod_vlan_pcp,修改报文的 VLAN 优先级,该选项会使 vlan_id 置为 0。
ovs-ofctl add-flow br0 in_port=1,actions=mod_vlan_pcp:7,output:2
# strip_vlan,剥掉报文内外层 VLAN tag。
ovs-ofctl add-flow br0 in_port=1,actions=strip_vlan,output:2
# 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:2
# NOTE:set_field 值为 4096+vlan_id,并且 vlan 优先级为 0,即 4096-8191,对应的 vlan_id 为 0-4095
# pop_vlan,弹出报文最外层 VLAN tag。
ovs-ofctl add-flow br0 in_port=1,dl_type=0x8100,dl_vlan=777,actions=pop_vlan,output:2
# 修改源/目的 MAC,修改源/目的 IP。
# 修改源 MAC
ovs-ofctl add-flow br0 in_port=1,actions=mod_dl_src:00:00:00:00:00:01,output:2
# 修改目的 MAC
ovs-ofctl add-flow br0 in_port=1,actions=mod_dl_dst:00:00:00:00:00:01,output:2
# 修改源 IP
ovs-ofctl add-flow br0 in_port=1,actions=mod_nw_src:192.168.1.1,output:2
# 修改目的 IP
ovs-ofctl add-flow br0 in_port=1,actions=mod_nw_dst:192.168.1.1,output:2
# 修改 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:2
# 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:2
# mod_nw_ecn,修改 ToS 字段的低 2 位,范围为 0-3,并且不会去修改 ToS 高 6 位的 DSCP 值。
ovs-ofctl add-flow br0 ip,in_port=1,actions=mod_nw_ecn:2,output:2
# mod_nw_ttl,修改 IP 报文 TTL 值,需要使用 Openflow1.1 以上版本兼容。
ovs-ofctl add-flow -O OpenFlow13 br0 in_port=1,actions=mod_nw_ttl:6,output:2
# dec_ttl,对 IP 报文进行 TTL 自减操作。
ovs-ofctl add-flow br0 in_port=1,actions=dec_ttl,output:2
# push_mpls,修改报文的 Ethertype,并且压入一个 MPLS LSE。
ovs-ofctl add-flow br0 in_port=1,actions=push_mpls:0x8847,set_field:10-\>mpls_label,output:2
# pop_mpls,剥掉最外层 MPLS Label,并且修改 Ethertype 为非 MPLS 类型。
ovs-ofctl add-flow br0 mpls,in_port=1,mpls_label=20,actions=pop_mpls:0x0800,output:2
# set_mpls_label,对报文最外层 MPLS 标签进行修改,范围为 20bit 值。
ovs-ofctl add-flow br0 in_port=1,actions=set_mpls_label:666,output:2
# set_mpls_tc,对报文最外层 MPPLS TC 进行修改,范围为 0-7。
ovs-ofctl add-flow br0 in_port=1,actions=set_mpls_tc:7,output:2
# set_mpls_ttl,对报文最外层 MPLS TTL 进行修改,范围为 0-255。
ovs-ofctl add-flow br0 in_port=1,actions=set_mpls_ttl:255,output:2
# dec_mpls_ttl,对报文最外层 MPLS TTL 进行自减操作。
ovs-ofctl add-flow br0 in_port=1,actions=dec_mpls_ttl,output:2
# move NXM,使用 move 参数对 NXM 字段进行操作。
# 将报文源 MAC 复制到目的 MAC 字段,并且将源 MAC 改为 00:00:00:00:00:01。
ovs-ofctl add-flow br0 in_port=1,actions=move:NXM_OF_ETH_SRC[]-\>NXM_OF_ETH_DST[],mod_dl_src:00:00:00:00:00:01,output:2
# load NXM,使用 load 参数对 NXM 字段进行赋值操作。
# push mpls label,并且把 10(0xa) 赋值给 MPLS Label。
ovs-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:2
# 指定 Group,group id 为已创建的 group table。
ovs-ofctl add-flow br0 in_port=1,actions=group:666
- 常用 NXM 字段参照表。
QoS
ingress policing
# 配置 ingress policing,对接口 eth0 入流限速 10Mbps
ovs-vsctl set interface eth0 ingress_policing_rate=10000
ovs-vsctl set interface eth0 ingress_policing_burst=8000
# 清除相应接口的 ingress policer 配置
ovs-vsctl set interface eth0 ingress_policing_rate=0
ovs-vsctl set interface eth0 ingress_policing_burst=0
# 查看接口 ingress policer 配置
ovs-vsctl list interface eth0
# 查看网桥支持的 QoS 类型
ovs-appctl qos/show-types br0
Overlay Tunnel
GRE
# 创建一个 GRE 接口,并且指定 OpenFlow Port ID 为 1001
ovs-vsctl add-port br0 gre1 -- set Interface gre1 type=gre options:remote_ip=1.1.1.1 ofport_request=1001
# (可选的)将 ToS 或者 TTL 在 Tunnel 上继承,并将 Tunnel id 设置成 123
ovs-vsctl set Interface gre1 options:tos=inherit options:ttl=inherit options:key=123
# 创建 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:1
VxLAN
# 创建一个 VxLAN 接口,并且指定 OpenFlow Port ID 为 2001
ovs-vsctl add-port br0 vxlan1 -- set Interface vxlan1 type=vxlan options:remote_ip=1.1.1.1 ofport_request=2001
# (可选的)将 ToS 或者 TTL 在 Tunnel 上继承,将 VNI 设置成 123,UDP 目的端为设置成 8472(默认为 4789)
ovs-vsctl set Interface vxlan1 options:tos=inherit options:ttl=inherit options:key=123 options:dst_port=8472
# 创建 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:1
sFlow
# 对 br0 进行 sFlow 监控
ovs-vsctl -- --id=@sflow create sflow agent=eth0 target=\"10.0.0.1:6343\" header=128 sampling=64 polling=10 -- set bridge br0 sflow=@sflow
# agent: 与 collector 通信所在的网口名,通常为管理口
# target: collector 监听的 IP 地址和端口,端口默认为 6343
# header: sFlow 在采样时截取报文头的长度
# polling: 采样时间间隔,单位为 s
# 查看创建的 sFlow
ovs-vsctl list sflow
# 删除对应的网桥 sFlow 配置,参数为 sFlow UUID
ovs-vsctl remove bridge br0 sflow 7b9b962e-fe09-407c-b224-5d37d9c1f2b3
# 删除网桥下所有 sFlow 配置
ovs-vsctl -- clear bridge br0 sflow
STP
# 开启/关闭指定 Bridge 的 STP
$ ovs-vsctl set bridge <bridge> stp_enable=true
$ ovs-vsctl set bridge <bridge> stp_enable=false
# 查询指定 Bridge 的 STP 的配置信息
$ ovs-vsctl get bridge <bridge> stp_enable
# 设置指定 Bridge 的 STP Priority
$ ovs−vsctl set bridge <bridge> other_config:stp-priority=0x7800
# 设置指定 Bridge 的 STP Cost
$ ovs−vsctl set bridge <bridge> other_config:stp-path-cost=10
端口镜像
# 配置 eth0 收到/发送的数据包镜像到 eth1。
ovs-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=@eth1
# 查看端口镜像配置
ovs-vsctl get bridge br0 mirrors
# 删除端口镜像配置
ovs-vsctl -- --id=@m get mirror mymirror -- remove bridge br0 mirrors @m
# 清除网桥下所有端口镜像配置
ovs-vsctl clear bridge br0 mirrors
端口聚合
# 创建一个聚合口
ovs-vsctl add-port br0 dpdkbond0 \
-- set interface dpdkbond0 type=dpdk options:dpdk-devargs=0000:01:00.0,0000:02:00.0
# 设置聚合口模式
# mode=1
ovs-vsctl set port dpdkbond0 bond_mode=active-backup
# mode=2
ovs-vsctl set port dpdkbond0 bond_mode=balance-slb
# mode=4
ovs-vsctl set port dpdkbond0 bond_mode=balance-tcp
ovs-vsctl set port dpdkbond0 lacp=active
ovs-vsctl set port dpdkbond0 lacp=off
ovs-vsctl set port dpdkbond0 lacp=passive
# 查看 mode=4 lacp 协商状态
ovs-appctl lacp/show
goto table 配置
数据流先从 table0 开始匹配,如 actions 有 goto_table,再进行后续 table 的匹配,实现多级流水线,如需使用 goto table,则创建流表时,指定 table id,范围为 0-255,不指定则默认为 table0。
# 在 table0 中添加一条流表条目。
ovs-ofctl add-flow br0 table=0,in_port=1,actions=goto_table=1
# 在 table1 中添加一条流表条目。
ovs-ofctl add-flow br0 table=1,ip,nw_dst=10.10.0.0/16,actions=output:2
group 表
由于 group 表是 Openflow1.1 版本以后才支持,所以所有命令需要指定 OpenFlow1.1 版本以上。
group 表支持 4 种类型:
- all:所有 buckets 都执行一遍。
- select: 每次选择其中一个 bucket 执行,常用于负载均衡应用。
- ff(FAST FAILOVER):快速故障修复,用于检测解决接口等故障。
- indirect:间接执行,类似于一个函数方法,被另一个 group 来调用。
# 查看当前设备对 group 的支持。
ovs-ofctl -O OpenFlow13 dump-group-features br0
# 查看 group 表。
ovs-ofctl -O OpenFlow13 dump-groups br0
# 创建 group 表。
# 类型为 all
ovs-ofctl -O OpenFlow13 add-group br0 group_id=1,type=all,bucket=output:1,bucket=output:2,bucket=output:3
# 类型为 select
ovs-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:3
# 删除 group 表。
ovs-ofctl -O OpenFlow13 del-groups br0 group_id=2
# 创建流表。
ovs-ofctl -O OpenFlow13 add-flow br0 in_port=1,actions=group:2
meter 表
meter 表是 Openflow1.3 版本以后才支持的特性,Open vSwitch 在 2.8 以后支持。
# 查看当前设备对 meter 的支持。
ovs-ofctl -O OpenFlow13 meter-features br0
# 查看 meter 表。
ovs-ofctl -O OpenFlow13 dump-meters br0
# 查看 meter 统计。
ovs-ofctl -O OpenFlow13 meter-stats br0
# 创建 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=1000
# 删除 meter 表。
# 删除全部 meter 表。
ovs-ofctl -O OpenFlow13 del-meters br0
# 删除 meter id=1。
ovs-ofctl -O OpenFlow13 del-meter br0 meter=1
# 创建流表。
ovs-ofctl -O OpenFlow13 add-flow br0 in_port=1,actions=meter:1,output:2