1. 端口说明

OVS支持如下的标准OpenFlow端口名称(括号中是端口号):

  • in_port (65528 or 0xfff8; 0xfffffff8)
  • table (65529 or 0xfff9; 0xfffffff9)
  • normal (65530 or 0xfffa; 0xfffffffa)
  • flood (65531 or 0xfffb; 0xfffffffb)
  • all (65532 or 0xfffc; 0xfffffffc)
  • controller (65533 or 0xfffd; 0xfffffffd)
  • local (65534 or 0xfffe; 0xfffffffe)
  • any or none (65535 or 0xffff; 0xffffffff)
  • unset (not in OpenFlow 1.0; 0xfffffff7)

2. Actions

OVS按如下顺序执行各个actions,且action set中每种类型的action只会存在一个,后加入的会替换之前加入的action:

  1. strip_vlan
  2. pop_mpls
  3. decap
  4. encap
  5. push_mpls
  6. push_vlan
  7. dec_ttl
  8. dec_mpls_ttl
  9. dec_nsh_ttl
  10. 如下action按添加顺序执行:
    • load
    • move
    • mod_dl_dst
    • mod_dl_src
    • mod_nw_dst
    • mod_nw_src
    • mod_nw_tos
    • mod_nw_ecn
    • mod_nw_ttl
    • mod_tp_dst
    • mod_tp_src
    • mod_vlan_pcp
    • mod_vlan_vid
    • set_field
    • set_tunnel
    • set_tunnel64
  11. set_queue
  12. group, output, resubmit, ct_clear, 或 ct。如果这些actions中出现多个,则按上述顺序执行第一个出现的action,余下的忽略。

2.1 输出动作

port
output:port
output:field
output(port=port, max_len=nbytes)

将数据包发送到物理端口或控制器;输出端口可以从field中读取;如果指定了max_len,则在输出之前会将数据包截断,以确保数据包长度不会超过max_len。

port可以支持如下标准OpenFlow端口:

  • local: 将数据包转发到与网桥具有相同名称的网络设备;
  • in_port: 将数据包转发到输入端口;

如果不指定max_len,则还可以支持如下端口:

  • normal: 进行正常的L2/L3处理;
  • flood: 将数据转发到所有的物理端口,除了输入端口和flooding被禁用的端口;
  • all: 将数据转发到所有的物理端口,除了输入端口;
  • controller: 将数据包及其元数据发送到一个或多个封装在OpenFlow packet-in消息中的控制器;

如,

$ ovs-ofctl add-flow br0 in_port=2,actions=in_port
$ ovs-ofctl add-flow br0 actions=2,3,4,5,6,in_port
$ ovs-ofctl add-flow br0 "in_port=2,actions=load:0->in_port,2"

2.2 控制器动作

controller
controller:max_len
controller(key[=value], ...)

将数据包及其元数据发送到一个或多个封装在OpenFlow packet-in消息中的控制器;支持的选项如下:

  • max_len=max_len: 限制要在packet-in中发送的数据包的字节数,最大为65535(默认值);
  • reason=reason: 指明发送的原因,支持的值有 no_match, action(默认),  invalid_ttl,  action_set, group, packet_out.
  • id=controller_id: 指定要发送到哪些控制器;
  • userdata=hh...: 使用十六进制表示的用户数据,十六进制数之间可用点号分隔;
  • pause

    Causes the switch to freeze the packet’s trip through Open vSwitch flow tables and serializes that state into
    the packet-in message as a ``continuation,’’ an additional property in the NXT_PACKET_IN2 message. The con‐
    troller can later send the continuation back to the switch in an NXT_RESUME message, which will restart the
    packet’s traversal from the point where it was interrupted. This permits an OpenFlow controller to interpose
    on a packet midway through processing in Open vSwitch.

2.3 入队列动作

enqueue(port,queue)
enqueue:port:queue

将数据包排入指定端口的指定队列;queue必须是0~4294967294 (0xfffffffe)间的整数;

2.4 组动作

group:group

将数据包输出到指定的组;group必须是0~4294967040 (0xffffff00)间的整数;

2.5 封装、解封动作

strip_vlan
pop_vlan

如果有的话,则移除最外面的VLAN标签。

push_vlan:ethertype 

在最外面压入VLAN标签;ethertype可以为0x8100(802.1Q C-tag)或0x88a8(802.1ad S-tag)。

push_mpls:ethertype

在最外层压入MPLS标签堆栈条目(LSE),并将数据包的Ethertype修改为ethertype,其中ethertype需为B0x8847或0x8848.

如果数据包已经包含一个MPLS标签,则新压入的标签是已有标签的拷贝。

pop_mpls:ethertype

剥离最外层的MPLS标签堆栈条目(LSE),并将数据包的Ethertype修改为ethertype;如果包含多个MPLS标签,则ethertype需为B0x8847或0x8848.

encap(nsh([md_type=md_type], [tlv(class,type,value)]...))
encap(ethernet)

使用指定的头部封装数据包。

第一种方式使用NSH封装以太网帧;其中,md_type可以为1(默认)或2;当md_type=2时,必须指定TLVs,且class是16位的十六进制数,type是8位的十进制数,value是十六进制数。

第二种方式将一个裸L3数据包封装在一个以太网帧中;Ethertype被初始化位L3数据包的类型;以太网源和目的地址被初始化位0.

如,

encap(nsh(md_type=1))
encap(nsh(md_type=2,tlv(0x1000,10,0x12345678)))

decap

移除最外层的封装。

2.6 字段修改动作

set_field:value[/mask]->dst
load:value->dst

将一个字面量加载到指定的字段或字段的某部分中;dst位字段名称。

对于load动作,value需是一个整数。如,

set_field:00:11:22:33:44:55->eth_src
load:0x001122334455->eth_src set_field:01:00:00:00:00:00/01:00:00:00:00:00->eth_dst
load:1->eth_dst[40]

move:src->dst

拷贝src到dst;src和dst可以是一个字段或字段的某部分。如,

move:reg0[0..5]->reg1[26..31]
move:reg0[0..15]->vlan_tci

mod_dl_src:mac
mod_dl_dst:mac

修改以太网(数据链路层)源或目的地址为mac;mac需为xx:xx:xx:xx:xx:xx的形式。

mod_nw_src:ip
mod_nw_dst:ip

修改IPv4(网络层)源或目的地址为ip;ip需为w.x.y.z的形式。

mod_nw_tos:tos
mod_nw_ecn:ecn

mod_nw_tos设置IPv4 ToS/DSCP中的DSCP位或IPv6的traffic class字段为tos;tos必须是0~255之间的4的倍数。

mod_nw_ecn设置IPv4 ToS或IPv6 traffic class字段为ecn;ecn必须是0~3的整数。

mod_tp_src:port
mod_tp_dst:port

修改TCP/UDP/SCTP(传输层)的源或目的端口为port。

dec_ttl
dec_ttl(id1, [id2]...)

递减IPv4数据包的TTL或IPv6数据包的跳限制。

set_mpls_label:label
set_mpls_tc:tc
set_mpls_ttl:ttl

set_mpls_label修改外层的MPLS标签堆栈条目的标签;label需是20为的整数,支持十进制和十六进制。

set_mpls_tc修改外层MPLS标签堆栈条目的traffic class;tc需是0~7间的整数。

set_mpls_ttl修改外层MPLS标签堆栈条目的TTL;ttl需为0~255间的整数。

dec_mpls_ttl
dec_nsh_ttl

递减外层MPLS标签堆栈条目或NSH头部的TTL。

2.7 元数据动作

set_tunnel:id
set_tunnel64:id

设置VXLAN/Geneve数据包的tunnel ID;set_tunnel64用于支持宽度超过32位的id。

set_queue:queue
pop_queue

set_queue设置队列ID;其中queue位32位的整数。

pop_queue还原输出队列为数据包进入交换机时设置的默认值(通常为0)。

2.8 防火墙动作

ct([argument]...)
ct(commit[, argument]...)

argument可为如下值:

  zone=value  设置zone为一个16位的id(默认位0),以将连接隔离在不同的域中;value可以是字面量,也可以是某给字段或字段的某部分。

如果没有commit,则会通过connection tracker发送数据包;连接跟踪器会跟踪通过它的数据包的TCP连接状态;对于通过连接的每个数据包,它检查它是否满足TCP不变量,并使用ct_state元数据字段向以后的操作发送连接状态信号。

此时,ct会fork流水线:

  • 在一个分叉中,ct将数据包传递给连接跟踪器。之后,它将数据包重新注入OpenFlow流水线,并初始化连接跟踪字段。ct_state字段用连接状态初始化、ct_zone用zone参数初始化。
  • 在另一个分叉中,数据包的原始实例在ct_action之后继续独立处理。ct_state字段和其他连接跟踪元数据都被清除。

ct action还支持如下argument:

  table=table  设置数据包要重新注入到哪个流表;如果不设置则不重新注入;

  nat
  nat(type=addrs[:ports][,flag]...)

    设置NAT;type需为src(SNAT)或dst(DNAT);为新连接设置NAT只有在该连接之后使用ct(commit...)提交才会生效;

    addrs  IP地址或地址范围addr1-addr2;指定可使用的地址范围;

    ports  L4端口或端口范围port1-port2;指定可使用的端口范围;

    flag支持如下值:

      random: 随机选择一个端口;

      hash: 使用哈希算法选择端口;

      persistent: 应从给定范围中选择IP地址,以便在系统重新启动后可以提供相同的映射。

如果有commit,则连接跟踪器会将连接提交到连接跟踪模块。commit标志只能在没有commit的ct的第一个分支中使用。

如,

# allows new connections from port 1 to port 2, and only allows
# established connections to send traffic from port 2 to port 1
table=0,priority=1,action=drop
table=0,priority=10,arp,action=normal
table=0,priority=100,ip,ct_state=-trk,action=ct(table=1)
table=1,in_port=1,ip,ct_state=+trk+new,action=ct(commit),2
table=1,in_port=1,ip,ct_state=+trk+est,action=2
table=1,in_port=2,ip,ct_state=+trk+new,action=drop
table=1,in_port=2,ip,ct_state=+trk+est,action=1

ct_clear

清除连接跟踪状态,将ct_state, ct_zone, ct_mark, ct_label清零。

learn(argument...)

添加或修改flow;argument指定了匹配字段、actions和其他参数。

匹配字段(至少需指定一个)可以有如下形式:

  field=value  value为字面量;

  field=src   其中src是当前正在处理的数据包中的某个字段;

  field   上一种形式的简写方式;

actions(至少需指定一个)可以有如下形式:

  load:value->dst  将value加载到dst;

  load:src->dst  将src加载到dst,其中,src和dst可以是某个字段或字段的某部分;

  output:field  输出端口从field中读取;

  fin_idle_timeout=seconds  设置idle timeout;
  fin_hard_timeout=seconds  设置hard timeout;

以下参数则是可选的:

  idle_timeout=seconds
  hard_timeout=seconds
  priority=value
  cookie=value
  send_flow_rem
  table=table
  delete_learned  删除包含learn action的流也会删除由learn创建的流;
  limit=number  如果新流的表中具有相同cookie的流的数目超过了该数目,则该操作不会添加新流;默认(limit=0)没有限制。

  result_dst=field[bit]  如果学习失败(因为流的数量超过限制),则将field[bit]设置为0,否则设置为1。field[bit]必须是单个位。

fin_timeout(key=value...)

修改idle timeout或hard timeout或两者。支持如下key=value,

  idle_timeout=seconds
  hard_timeout=seconds

2.9 编程和控制流动作

resubmit:port
resubmit([port],[table][,ct])

在流表中搜索匹配的流并执行找到的动作(如果有的话),然后在当前流项中继续执行接下来的动作。支持以下参数:

  • port: 指定用于输入端口元数据字段的值,作为搜索的一部分,以代替流中当前的输入端口。
  • table: 指定要搜索的流表,默认为当前流表。
  • ct: 将数据包的5元组字段和对应的conntrack原始方向元组字段交换。

clone(action...)

执行每个嵌套的动作,事先保存大部分数据包和流水线状态,然后再恢复。

push:src
pop:dst

push将src压入堆栈,而pop则弹出栈顶元素至dst中;src和dst都是某个字段或字段的某部分。如,

push:reg2[0..5]
pop:reg2[0..5]

exit

退出,不再执行后续动作;如果exit处于group bucket中,则只是退出当前bucket而已。

multipath(fields, basis, algorithm, n_links, arg, dst)

使用basis作为哈希参数对fields进行哈希,然后使用参数arg应用多路径链路选择算法输出0~n_links-1之间的整数,并存储到dst中。

fields必须是如下字段:

  eth_src  以太网源地址。

  symmetric_l4  以太网源和目的地址、类型、VLAN ID、IPv4/IPv6源和目的地址、协议、TCP/SCTP端口号。

  symmetric_l3l4  IPv4/IPv6源和目的地址、协议、TCP/SCTP端口号。

  symmetric_l3l4+udp  IPv4/IPv6源和目的地址、协议、TCP/SCTP/UDP端口号。

  symmetric_l3  IPv4/IPv6源和目的地址。

  nw_src  网络层源地址。

  nw_dst  网络层目的地址。

algorithm必须是如下值之一:

  modulo_n    link = hash(flow) % n_links.

  hash_threshold  link = hash(flow) / (MAX_HASH / n_links).

  hrw (Highest Random Weight)

    for i in [0,n_links]:
      weights[i] = hash(flow, i)
    link = { i such that weights[i] >= weights[j] for all j != i }

  iter_hash (Iterative Hash)

    i = 0
    repeat:
      i = i + 1
      link = hash(flow, i) % arg
    while link > max_link

只有iter_hash需要使用arg参数。

参考资料

https://www.openvswitch.org/support/dist-docs/ovs-actions.7.txt

ovs-actions的更多相关文章

  1. ovs 删除流表 指定 actions 中字段

    例: ovs-ofctl del-flows br-int in_port=100,out_group=100 -O openflow13 ovs-ofctl del-flows br-int in_ ...

  2. Neutron 理解 (4): Neutron OVS OpenFlow 流表 和 L2 Population [Netruon OVS OpenFlow tables + L2 Population]

    学习 Neutron 系列文章: (1)Neutron 所实现的虚拟化网络 (2)Neutron OpenvSwitch + VLAN 虚拟网络 (3)Neutron OpenvSwitch + GR ...

  3. 探索 OpenStack 之(7):Neutron 深入探索之 Open vSwitch (OVS) + GRE 之 Neutron节点篇

    0. 测试环境 硬件环境:还是使用四节点OpenStack部署环境,参见 http://www.cnblogs.com/sammyliu/p/4190843.html OpenStack配置: ten ...

  4. 学习OpenStack之(6):Neutron 深入学习之 OVS + GRE 之 Compute node 篇

    0.环境 硬件环境见上一篇博客:学习OpenStack之(5):在Mac上部署Juno版本OpenStack 四节点环境 OpenStack网络配置:一个tenant, 2个虚机 Type drive ...

  5. Openstack Neutron OVS ARP Responder

    ARP – Why do we need it? In any environment, be it the physical data-center, your home, or a virtual ...

  6. OVS ARP Responder – Theory and Practice

    Prefix In the GRE tunnels post I’ve explained how overlay networks are used for connectivity and ten ...

  7. SDN环境搭建(mininet,OVS,ryu安装及命令)

    1.mininet安装与使用 1.1mininet安装 ubuntu 12.04/14.04/14.10      命令行  sudo apt-get install mininet 1.2 mini ...

  8. OVS操作总结

    转载:http://www.aboutyun.com/thread-11777-1-1.html Open vSwitch(下面简称为 OVS)是由 Nicira Networks 主导的,运行在虚拟 ...

  9. ubuntu 14.04设备OVS虚拟OpenFlow交换机配置汇总

    一.设备OVS sudo apt-get install openvswitch-controller openvswitch-switch openvswitch-datapath-source ( ...

  10. OvS: ovs-ofctl adding parameters analysis

    if using dpdk, then OvS' datapath folder is ignored. Only OvS' userspace code are in use. According ...

随机推荐

  1. 我用 go-zero 一周实现了一个中台系统,已开源!

    作者:Jack 最近发现golang社区里出了一个新星的微服务框架,来自好未来,光看这个名字,就很有奔头,之前,也只是玩过go-micro,其实真正的还没有在项目中运用过,只是觉得 微服务,grpc ...

  2. 用Python分析北京市蛋壳公寓租房数据

    本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,如有问题请及时联系我们以作处理 近期,蛋壳公寓"爆雷"事件持续发酵,期间因拖欠房东房租与租客退款,蛋壳公寓陷入讨 ...

  3. 手把手教你使用Python轻松搞定发邮件

    前言 现在生活节奏加快,人们之间交流方式也有了天差地别,为了更加便捷的交流沟通,电子邮件产生了,众所周知,电子邮件其实就是客户端和服务器端发送接受数据一样,他有一个发信和一个收信的功能,电子邮件的通信 ...

  4. CCNP之二层技术

    二层技术 ---数据链路层 核心功能:介质访问控制功能,控制物理层 网络类型: 1)MA:multiple access 多路访问(指在一条链路上有多个访问点,区别于点到点或点到多点的网络) BMA: ...

  5. 前台js获取url传递参数(后台Request.QueryString接收)

    方法 封装 function GetQueryString(name) { var reg = new RegExp("(^|&)" + name + "=([^ ...

  6. 浅析 TensorFlow Runtime 技术

    关于 TF Runtime 的疑问? 什么是TFRT ? TensorFlow Runtime,简称 TFRT,它提供了统一的.可扩展的基础架构层,可以极致地发挥CPU多线程性能,支持全异步编程(无锁 ...

  7. [leetcode]297. Serialize and Deserialize Binary Tree一般二叉树的编解码

    由于一般的前序遍历不能唯一的还原出原本你的二叉树,所以要改变一下: 记录二叉树的结构信息,也就是空节点用符号表示 一般的前序遍历只是记录了节点的前后顺序,通过记录空节点,每一层的结构就可以记录下来 解 ...

  8. request常用方法servlet初步

    1 package com.ycw.newservlet; 2 3 import java.io.IOException; 4 import javax.servlet.ServletExceptio ...

  9. 探讨EFCore如何优雅的实现读写分离

    前言     我们都知道当单库系统遇到性能瓶颈时,读写分离是首要优化手段之一.因为绝大多数系统读的比例远高于写的比例,并且大量耗时的读操作容易引起锁表导致无发写入数据,这时读写分离就更加重要了.   ...

  10. .NET的并发编程(TPL编程)是什么?

    写在前面 优秀软件的一个关键特征就是具有并发性.过去的几十年,我们可以进行并发编程,但是难度很大.以前,并发性软件的编写.调试和维护都很难,这导致很多开发人员为图省事放弃了并发编程.新版 .NET 中 ...