OpenFlow v1.2 消息和结构

控制器到交换机消息

握手

class os_ken.ofproto.ofproto_v1_2_parser.OFPFeaturesRequest(datapath)

功能请求消息

控制器在会话建立后向交换机发送功能请求。

此消息由 OSKen 框架处理,因此 OSKen 应用程序通常不需要处理此消息。

示例

def send_features_request(self, datapath):
    ofp_parser = datapath.ofproto_parser

    req = ofp_parser.OFPFeaturesRequest(datapath)
    datapath.send_msg(req)

JSON 示例

{
   "OFPFeaturesRequest": {}
}
class os_ken.ofproto.ofproto_v1_2_parser.OFPSwitchFeatures(datapath, datapath_id=None, n_buffers=None, n_tables=None, capabilities=None, ports=None)

功能回复消息

交换机响应功能请求,发送功能回复消息。

此消息由 OSKen 框架处理,因此 OSKen 应用程序通常不需要处理此消息。

示例

@set_ev_cls(ofp_event.EventOFPSwitchFeatures, CONFIG_DISPATCHER)
def switch_features_handler(self, ev):
    msg = ev.msg

    self.logger.debug('OFPSwitchFeatures received: '
                      'datapath_id=0x%016x n_buffers=%d '
                      'n_tables=%d capabilities=0x%08x ports=%s',
                      msg.datapath_id, msg.n_buffers, msg.n_tables,
                      msg.capabilities, msg.ports)

JSON 示例

{
   "OFPSwitchFeatures": {
      "capabilities": 79,
      "datapath_id": 9210263729383,
      "n_buffers": 0,
      "n_tables": 255,
      "ports": {
         "6": {
            "OFPPort": {
               "advertised": 10240,
               "config": 0,
               "curr": 10248,
               "curr_speed": 5000,
               "hw_addr": "f2:0b:a4:7d:f8:ea",
               "max_speed": 5000,
               "name": "Port6",
               "peer": 10248,
               "port_no": 6,
               "state": 4,
               "supported": 10248
            }
         },
         "7": {
            "OFPPort": {
               "advertised": 10240,
               "config": 0,
               "curr": 10248,
               "curr_speed": 5000,
               "hw_addr": "f2:0b:a4:d0:3f:70",
               "max_speed": 5000,
               "name": "Port7",
               "peer": 10248,
               "port_no": 7,
               "state": 4,
               "supported": 10248
            }
         }
      }
   }
}

交换机配置

class os_ken.ofproto.ofproto_v1_2_parser.OFPSetConfig(datapath, flags=0, miss_send_len=0)

设置配置请求消息

控制器发送设置配置请求消息以设置配置参数。

属性

描述

flags

以下配置标志之一。

OFPC_FRAG_NORMAL
OFPC_FRAG_DROP
OFPC_FRAG_REASM
OFPC_FRAG_MASK
OFPC_INVALID_TTL_TO_CONTROLLER

miss_send_len

数据路径应发送到控制器的最大新流字节数

示例

def send_set_config(self, datapath):
    ofp = datapath.ofproto
    ofp_parser = datapath.ofproto_parser

    req = ofp_parser.OFPSetConfig(datapath, ofp.OFPC_FRAG_NORMAL, 256)
    datapath.send_msg(req)

JSON 示例

{
   "OFPSetConfig": {
      "flags": 0,
      "miss_send_len": 128
   }
}
class os_ken.ofproto.ofproto_v1_2_parser.OFPGetConfigRequest(datapath)

获取配置请求消息

控制器发送获取配置请求以查询交换机中的配置参数。

示例

def send_get_config_request(self, datapath):
    ofp_parser = datapath.ofproto_parser

    req = ofp_parser.OFPGetConfigRequest(datapath)
    datapath.send_msg(req)

JSON 示例

{
   "OFPGetConfigRequest": {}
}
class os_ken.ofproto.ofproto_v1_2_parser.OFPGetConfigReply(datapath, flags=None, miss_send_len=None)

获取配置回复消息

交换机响应配置请求,发送获取配置回复消息。

属性

描述

flags

以下配置标志之一。

OFPC_FRAG_NORMAL
OFPC_FRAG_DROP
OFPC_FRAG_REASM
OFPC_FRAG_MASK
OFPC_INVALID_TTL_TO_CONTROLLER

miss_send_len

数据路径应发送到控制器的最大新流字节数

示例

@set_ev_cls(ofp_event.EventOFPGetConfigReply, MAIN_DISPATCHER)
def get_config_reply_handler(self, ev):
    msg = ev.msg
    dp = msg.datapath
    ofp = dp.ofproto

    if msg.flags == ofp.OFPC_FRAG_NORMAL:
        flags = 'NORMAL'
    elif msg.flags == ofp.OFPC_FRAG_DROP:
        flags = 'DROP'
    elif msg.flags == ofp.OFPC_FRAG_REASM:
        flags = 'REASM'
    elif msg.flags == ofp.OFPC_FRAG_MASK:
        flags = 'MASK'
    elif msg.flags == ofp.OFPC_INVALID_TTL_TO_CONTROLLER:
        flags = 'INVALID TTL TO CONTROLLER'
    else:
        flags = 'unknown'
    self.logger.debug('OFPGetConfigReply received: '
                      'flags=%s miss_send_len=%d',
                      flags, msg.miss_send_len)

JSON 示例

{
   "OFPGetConfigReply": {
      "flags": 0,
      "miss_send_len": 128
   }
}

流表配置

class os_ken.ofproto.ofproto_v1_2_parser.OFPTableMod(datapath, table_id, config)

流表配置消息

控制器发送此消息以配置表状态。

属性

描述

table_id

表的 ID(OFPTT_ALL 表示所有表)

config

以下标志的位图。

OFPTC_TABLE_MISS_CONTROLLER
OFPTC_TABLE_MISS_CONTINUE
OFPTC_TABLE_MISS_DROP
OFPTC_TABLE_MISS_MASK

示例

def send_table_mod(self, datapath):
    ofp = datapath.ofproto
    ofp_parser = datapath.ofproto_parser

    req = ofp_parser.OFPTableMod(datapath, ofp.OFPTT_ALL,
                                 ofp.OFPTC_TABLE_MISS_DROP)
    datapath.send_msg(req)

JSON 示例

{
   "OFPTableMod": {
      "config": 0,
      "table_id": 255
   }
}

修改状态消息

class os_ken.ofproto.ofproto_v1_2_parser.OFPFlowMod(datapath, cookie=0, cookie_mask=0, table_id=0, command=0, idle_timeout=0, hard_timeout=0, priority=0, buffer_id=4294967295, out_port=0, out_group=0, flags=0, match=None, instructions=None)

修改流条目消息

控制器发送此消息以修改流表。

属性

描述

cookie

不透明的控制器颁发的标识符

cookie_mask

用于限制在命令为 OPFFC_MODIFY*OFPFC_DELETE* 时必须匹配的 cookie 位的掩码

table_id

要将流放入的表的 ID

command

以下值之一。

OFPFC_ADD
OFPFC_MODIFY
OFPFC_MODIFY_STRICT
OFPFC_DELETE
OFPFC_DELETE_STRICT

idle_timeout

丢弃前的空闲时间(秒)

hard_timeout

丢弃前的最大时间(秒)

priority

流条目的优先级

buffer_id

要应用的缓冲数据包(或 OFP_NO_BUFFER)

out_port

对于 OFPFC_DELETE* 命令,要求匹配的条目包含此作为输出端口

out_group

对于 OFPFC_DELETE* 命令,要求匹配的条目包含此作为输出组

flags

以下值之一。

OFPFF_SEND_FLOW_REM
OFPFF_CHECK_OVERLAP
OFPFF_RESET_COUNTS

match

OFPMatch 的实例

instructions

OFPInstruction* 实例列表

示例

def send_flow_mod(self, datapath):
    ofp = datapath.ofproto
    ofp_parser = datapath.ofproto_parser

    cookie = cookie_mask = 0
    table_id = 0
    idle_timeout = hard_timeout = 0
    priority = 32768
    buffer_id = ofp.OFP_NO_BUFFER
    match = ofp_parser.OFPMatch(in_port=1, eth_dst='ff:ff:ff:ff:ff:ff')
    actions = [ofp_parser.OFPActionOutput(ofp.OFPP_NORMAL, 0)]
    inst = [ofp_parser.OFPInstructionActions(ofp.OFPIT_APPLY_ACTIONS,
                                             actions)]
    req = ofp_parser.OFPFlowMod(datapath, cookie, cookie_mask,
                                table_id, ofp.OFPFC_ADD,
                                idle_timeout, hard_timeout,
                                priority, buffer_id,
                                ofp.OFPP_ANY, ofp.OFPG_ANY,
                                ofp.OFPFF_SEND_FLOW_REM,
                                match, inst)
    datapath.send_msg(req)

JSON 示例

{
   "OFPFlowMod": {
      "buffer_id": 65535,
      "command": 0,
      "cookie": 0,
      "cookie_mask": 0,
      "flags": 0,
      "hard_timeout": 0,
      "idle_timeout": 0,
      "instructions": [
         {
            "OFPInstructionActions": {
               "actions": [
                  {
                     "OFPActionSetField": {
                        "field": {
                           "OXMTlv": {
                              "field": "vlan_vid",
                              "mask": null,
                              "value": 258
                           }
                        },
                        "len": 16,
                        "type": 25
                     }
                  },
                  {
                     "OFPActionOutput": {
                        "len": 16,
                        "max_len": 65535,
                        "port": 6,
                        "type": 0
                     }
                  }
               ],
               "len": 40,
               "type": 3
            }
         },
         {
            "OFPInstructionActions": {
               "actions": [
                  {
                     "OFPActionSetField": {
                        "field": {
                           "OXMTlv": {
                              "field": "eth_src",
                              "mask": null,
                              "value": "01:02:03:04:05:06"
                           }
                        },
                        "len": 16,
                        "type": 25
                     }
                  }
               ],
               "len": 24,
               "type": 4
            }
         }
      ],
      "match": {
         "OFPMatch": {
            "length": 14,
            "oxm_fields": [
               {
                  "OXMTlv": {
                     "field": "eth_dst",
                     "mask": null,
                     "value": "f2:0b:a4:7d:f8:ea"
                  }
               }
            ],
            "type": 1
         }
      },
      "out_group": 4294967295,
      "out_port": 4294967295,
      "priority": 123,
      "table_id": 1
   }
}
{
   "OFPFlowMod": {
      "buffer_id": 65535,
      "command": 0,
      "cookie": 0,
      "cookie_mask": 0,
      "flags": 0,
      "hard_timeout": 0,
      "idle_timeout": 0,
      "instructions": [
         {
            "OFPInstructionGotoTable": {
               "len": 8,
               "table_id": 1,
               "type": 1
            }
         }
      ],
      "match": {
         "OFPMatch": {
            "length": 22,
            "oxm_fields": [
               {
                  "OXMTlv": {
                     "field": "in_port",
                     "mask": null,
                     "value": 6
                  }
               },
               {
                  "OXMTlv": {
                     "field": "eth_src",
                     "mask": null,
                     "value": "f2:0b:a4:7d:f8:ea"
                  }
               }
            ],
            "type": 1
         }
      },
      "out_group": 4294967295,
      "out_port": 4294967295,
      "priority": 123,
      "table_id": 0
   }
}
class os_ken.ofproto.ofproto_v1_2_parser.OFPGroupMod(datapath, command=0, type_=0, group_id=0, buckets=None)

修改组条目消息

控制器发送此消息以修改组表。

属性

描述

command

以下值之一。

OFPGC_ADD
OFPGC_MODIFY
OFPGC_DELETE

type

以下值之一。

OFPGT_ALL
OFPGT_SELECT
OFPGT_INDIRECT
OFPGT_FF

group_id

组标识符

buckets

OFPBucket 列表

type 属性对应于 __init__ 的 type_ 参数。

示例

def send_group_mod(self, datapath):
    ofp = datapath.ofproto
    ofp_parser = datapath.ofproto_parser

    port = 1
    max_len = 2000
    actions = [ofp_parser.OFPActionOutput(port, max_len)]

    weight = 100
    watch_port = 0
    watch_group = 0
    buckets = [ofp_parser.OFPBucket(weight, watch_port, watch_group,
                                    actions)]

    group_id = 1
    req = ofp_parser.OFPGroupMod(datapath, ofp.OFPGC_ADD,
                                 ofp.OFPGT_SELECT, group_id, buckets)
    datapath.send_msg(req)

JSON 示例

{
   "OFPGroupMod": {
      "buckets": [
         {
            "OFPBucket": {
               "actions": [
                  {
                     "OFPActionOutput": {
                        "len": 16,
                        "max_len": 65535,
                        "port": 2,
                        "type": 0
                     }
                  }
               ],
               "len": 32,
               "watch_group": 1,
               "watch_port": 1,
               "weight": 1
            }
         }
      ],
      "command": 0,
      "group_id": 1,
      "type": 0
   }
}
class os_ken.ofproto.ofproto_v1_2_parser.OFPPortMod(datapath, port_no=0, hw_addr='00:00:00:00:00:00', config=0, mask=0, advertise=0)

端口修改消息

控制器发送此消息以修改端口的行为。

属性

描述

port_no

要修改的端口号

hw_addr

必须与 OFPSwitchFeaturesOFPPort 的 hw_addr 相同的硬件地址

config

配置标志的位图。

OFPPC_PORT_DOWN
OFPPC_NO_RECV
OFPPC_NO_FWD
OFPPC_NO_PACKET_IN

mask

要更改的上述配置标志的位图

advertise

以下标志的位图。

OFPPF_10MB_HD
OFPPF_10MB_FD
OFPPF_100MB_HD
OFPPF_100MB_FD
OFPPF_1GB_HD
OFPPF_1GB_FD
OFPPF_10GB_FD
OFPPF_40GB_FD
OFPPF_100GB_FD
OFPPF_1TB_FD
OFPPF_OTHER
OFPPF_COPPER
OFPPF_FIBER
OFPPF_AUTONEG
OFPPF_PAUSE
OFPPF_PAUSE_ASYM

示例

def send_port_mod(self, datapath):
    ofp = datapath.ofproto
    ofp_parser = datapath.ofproto_parser

    port_no = 3
    hw_addr = 'fa:c8:e8:76:1d:7e'
    config = 0
    mask = (ofp.OFPPC_PORT_DOWN | ofp.OFPPC_NO_RECV |
            ofp.OFPPC_NO_FWD | ofp.OFPPC_NO_PACKET_IN)
    advertise = (ofp.OFPPF_10MB_HD | ofp.OFPPF_100MB_FD |
                 ofp.OFPPF_1GB_FD | ofp.OFPPF_COPPER |
                 ofp.OFPPF_AUTONEG | ofp.OFPPF_PAUSE |
                 ofp.OFPPF_PAUSE_ASYM)
    req = ofp_parser.OFPPortMod(datapath, port_no, hw_addr, config,
                                mask, advertise)
    datapath.send_msg(req)

JSON 示例

{
   "OFPPortMod": {
      "advertise": 4096,
      "config": 0,
      "hw_addr": "00-11-00-00-11-11",
      "mask": 0,
      "port_no": 1
   }
}

读取状态消息

class os_ken.ofproto.ofproto_v1_2_parser.OFPDescStatsRequest(datapath, flags=0)

描述统计请求消息

控制器使用此消息查询交换机的描述。

属性

描述

flags

零(规范中尚未定义)

示例

def send_desc_stats_request(self, datapath):
    ofp_parser = datapath.ofproto_parser

    req = ofp_parser.OFPDescStatsRequest(datapath)
    datapath.send_msg(req)

JSON 示例

{
   "OFPDescStatsRequest": {
      "flags": 0
   }
}
class os_ken.ofproto.ofproto_v1_2_parser.OFPDescStats(mfr_desc, hw_desc, sw_desc, serial_num, dp_desc)

描述统计回复消息

交换机通过包含此消息的统计回复响应描述统计请求。

属性

描述

mfr_desc

制造商描述

hw_desc

硬件描述

sw_desc

软件描述

serial_num

序列号

dp_desc

数据路径的人类可读描述

示例

@set_ev_cls(ofp_event.EventOFPStatsReply, MAIN_DISPATCHER)
def stats_reply_handler(self, ev):
    msg = ev.msg
    ofp = msg.datapath.ofproto
    body = ev.msg.body

    if msg.type == ofp.OFPST_DESC:
        self.desc_stats_reply_handler(body)

def desc_stats_reply_handler(self, body):
    self.logger.debug('DescStats: mfr_desc=%s hw_desc=%s sw_desc=%s '
                      'serial_num=%s dp_desc=%s',
                      body.mfr_desc, body.hw_desc, body.sw_desc,
                      body.serial_num, body.dp_desc)

JSON 示例

{
   "OFPStatsReply": {
      "body": {
         "OFPDescStats": {
            "dp_desc": "dp",
            "hw_desc": "hw",
            "mfr_desc": "mfr",
            "serial_num": "serial",
            "sw_desc": "sw"
         }
      },
      "flags": 0,
      "type": 0
   }
}
class os_ken.ofproto.ofproto_v1_2_parser.OFPFlowStatsRequest(datapath, table_id=255, out_port=4294967295, out_group=4294967295, cookie=0, cookie_mask=0, match=None, flags=0)

单个流统计请求消息

控制器使用此消息查询单个流统计信息。

属性

描述

table_id

要读取的表 ID

out_port

要求匹配的条目将此作为输出端口包含在内

out_group

要求匹配的条目将此作为输出组包含在内

cookie

要求匹配的条目包含此 cookie 值

cookie_mask

用于限制必须匹配的 cookie 位的掩码

match

OFPMatch 的实例

flags

零(规范中尚未定义)

示例

def send_flow_stats_request(self, datapath):
    ofp = datapath.ofproto
    ofp_parser = datapath.ofproto_parser

    cookie = cookie_mask = 0
    match = ofp_parser.OFPMatch(in_port=1)
    req = ofp_parser.OFPFlowStatsRequest(datapath,
                                         ofp.OFPTT_ALL,
                                         ofp.OFPP_ANY, ofp.OFPG_ANY,
                                         cookie, cookie_mask, match)
    datapath.send_msg(req)

JSON 示例

{
   "OFPFlowStatsRequest": {
      "cookie": 0,
      "cookie_mask": 0,
      "flags": 0,
      "match": {
         "OFPMatch": {
            "length": 4,
            "oxm_fields": [],
            "type": 1
         }
      },
      "out_group": 4294967295,
      "out_port": 4294967295,
      "table_id": 0
   }
}
class os_ken.ofproto.ofproto_v1_2_parser.OFPFlowStats(table_id, duration_sec, duration_nsec, priority, idle_timeout, hard_timeout, cookie, packet_count, byte_count, match, instructions=None, length=None)

单个流统计回复消息

交换机通过包含此消息的统计回复响应单个流统计请求。

属性

描述

table_id

来自流的表 ID

duration_sec

流存活的时间,以秒为单位

duration_nsec

超出 duration_sec 的流存活时间,以纳秒为单位

priority

条目的优先级

idle_timeout

到期前的空闲秒数

hard_timeout

到期前的秒数

cookie

不透明的控制器颁发的标识符

packet_count

流中的数据包数

byte_count

流中的字节数

match

OFPMatch 的实例

instructions

OFPInstruction* 实例列表

示例

@set_ev_cls(ofp_event.EventOFPStatsReply, MAIN_DISPATCHER)
def stats_reply_handler(self, ev):
    msg = ev.msg
    ofp = msg.datapath.ofproto
    body = ev.msg.body

    if msg.type == ofp.OFPST_FLOW:
         self.flow_stats_reply_handler(body)

def flow_stats_reply_handler(self, body):
    flows = []
    for stat in body:
        flows.append('table_id=%s '
                     'duration_sec=%d duration_nsec=%d '
                     'priority=%d '
                     'idle_timeout=%d hard_timeout=%d '
                     'cookie=%d packet_count=%d byte_count=%d '
                     'match=%s instructions=%s' %
                     (stat.table_id,
                      stat.duration_sec, stat.duration_nsec,
                      stat.priority,
                      stat.idle_timeout, stat.hard_timeout,
                      stat.cookie, stat.packet_count, stat.byte_count,
                      stat.match, stat.instructions))
    self.logger.debug('FlowStats: %s', flows)

JSON 示例

{
   "OFPStatsReply": {
      "body": [
         {
            "OFPFlowStats": {
               "byte_count": 0,
               "cookie": 0,
               "duration_nsec": 115277000,
               "duration_sec": 358,
               "hard_timeout": 0,
               "idle_timeout": 0,
               "instructions": [],
               "length": 56,
               "match": {
                  "OFPMatch": {
                     "length": 4,
                     "oxm_fields": [],
                     "type": 1
                  }
               },
               "packet_count": 0,
               "priority": 65535,
               "table_id": 0
            }
         },
         {
            "OFPFlowStats": {
               "byte_count": 0,
               "cookie": 0,
               "duration_nsec": 115055000,
               "duration_sec": 358,
               "hard_timeout": 0,
               "idle_timeout": 0,
               "instructions": [
                  {
                     "OFPInstructionActions": {
                        "actions": [
                           {
                              "OFPActionOutput": {
                                 "len": 16,
                                 "max_len": 0,
                                 "port": 4294967290,
                                 "type": 0
                              }
                           }
                        ],
                        "len": 24,
                        "type": 4
                     }
                  }
               ],
               "length": 88,
               "match": {
                  "OFPMatch": {
                     "length": 10,
                     "oxm_fields": [
                        {
                           "OXMTlv": {
                              "field": "eth_type",
                              "mask": null,
                              "value": 2054
                           }
                        }
                     ],
                     "type": 1
                  }
               },
               "packet_count": 0,
               "priority": 65534,
               "table_id": 0
            }
         },
         {
            "OFPFlowStats": {
               "byte_count": 238,
               "cookie": 0,
               "duration_nsec": 511582000,
               "duration_sec": 316220,
               "hard_timeout": 0,
               "idle_timeout": 0,
               "instructions": [
                  {
                     "OFPInstructionGotoTable": {
                        "len": 8,
                        "table_id": 1,
                        "type": 1
                     }
                  }
               ],
               "length": 80,
               "match": {
                  "OFPMatch": {
                     "length": 22,
                     "oxm_fields": [
                        {
                           "OXMTlv": {
                              "field": "in_port",
                              "mask": null,
                              "value": 6
                           }
                        },
                        {
                           "OXMTlv": {
                              "field": "eth_src",
                              "mask": null,
                              "value": "f2:0b:a4:7d:f8:ea"
                           }
                        }
                     ],
                     "type": 1
                  }
               },
               "packet_count": 3,
               "priority": 123,
               "table_id": 0
            }
         },
         {
            "OFPFlowStats": {
               "byte_count": 98,
               "cookie": 0,
               "duration_nsec": 980901000,
               "duration_sec": 313499,
               "hard_timeout": 0,
               "idle_timeout": 0,
               "instructions": [
                  {
                     "OFPInstructionActions": {
                        "actions": [
                           {
                              "OFPActionOutput": {
                                 "len": 16,
                                 "max_len": 65535,
                                 "port": 4294967293,
                                 "type": 0
                              }
                           }
                        ],
                        "len": 24,
                        "type": 3
                     }
                  }
               ],
               "length": 80,
               "match": {
                  "OFPMatch": {
                     "length": 4,
                     "oxm_fields": [],
                     "type": 1
                  }
               },
               "packet_count": 1,
               "priority": 0,
               "table_id": 0
            }
         }
      ],
      "flags": 0,
      "type": 1
   }
}
class os_ken.ofproto.ofproto_v1_2_parser.OFPAggregateStatsRequest(datapath, table_id=255, out_port=4294967295, out_group=4294967295, cookie=0, cookie_mask=0, match=None, flags=0)

聚合流统计请求消息

控制器使用此消息查询聚合流统计信息。

属性

描述

table_id

要读取的表 ID

out_port

要求匹配的条目将此作为输出端口包含在内

out_group

要求匹配的条目将此作为输出组包含在内

cookie

要求匹配的条目包含此 cookie 值

cookie_mask

用于限制必须匹配的 cookie 位的掩码

match

OFPMatch 的实例

flags

零(规范中尚未定义)

示例

def send_aggregate_stats_request(self, datapath):
    ofp = datapath.ofproto
    ofp_parser = datapath.ofproto_parser

    cookie = cookie_mask = 0
    match = ofp_parser.OFPMatch(in_port=1)
    req = ofp_parser.OFPAggregateStatsRequest(datapath, 0,
                                              ofp.OFPTT_ALL,
                                              ofp.OFPP_ANY,
                                              ofp.OFPG_ANY,
                                              cookie, cookie_mask,
                                              match)
    datapath.send_msg(req)

JSON 示例

{
   "OFPAggregateStatsRequest": {
      "cookie": 0,
      "cookie_mask": 0,
      "flags": 0,
      "match": {
         "OFPMatch": {
            "length": 4,
            "oxm_fields": [],
            "type": 1
         }
      },
      "out_group": 4294967295,
      "out_port": 4294967295,
      "table_id": 255
   }
}
class os_ken.ofproto.ofproto_v1_2_parser.OFPAggregateStatsReply(packet_count, byte_count, flow_count)

聚合流统计回复消息

交换机用包含此消息的统计回复响应聚合流统计请求。

属性

描述

packet_count

流中数据包的数量

byte_count

流中字节的数量

flow_count

流的数量

示例

@set_ev_cls(ofp_event.EventOFPStatsReply, MAIN_DISPATCHER)
def stats_reply_handler(self, ev):
    msg = ev.msg
    ofp = msg.datapath.ofproto
    body = ev.msg.body

    if msg.type == ofp.OFPST_AGGREGATE:
        self.aggregate_stats_reply_handler(body)

def aggregate_stats_reply_handler(self, body):
    self.logger.debug('AggregateStats: packet_count=%d byte_count=%d '
                      'flow_count=%d',
                      body.packet_count, body.byte_count,
                      body.flow_count)

JSON 示例

{
   "OFPStatsReply": {
      "body": {
         "OFPAggregateStatsReply": {
            "byte_count": 574,
            "flow_count": 6,
            "packet_count": 7
         }
      },
      "flags": 0,
      "type": 2
   }
}
class os_ken.ofproto.ofproto_v1_2_parser.OFPTableStatsRequest(datapath, flags=0)

表统计请求消息

控制器使用此消息查询流表统计信息。

属性

描述

flags

零(规范中尚未定义)

示例

def send_table_stats_request(self, datapath):
    ofp_parser = datapath.ofproto_parser

    req = ofp_parser.OFPTableStatsRequest(datapath)
    datapath.send_msg(req)

JSON 示例

{
   "OFPTableStatsRequest": {
      "flags": 0
   }
}
class os_ken.ofproto.ofproto_v1_2_parser.OFPTableStats(table_id, name, match, wildcards, write_actions, apply_actions, write_setfields, apply_setfields, metadata_match, metadata_write, instructions, config, max_entries, active_count, lookup_count, matched_count)

表统计回复消息

交换机用包含此消息的统计回复响应表统计请求。

属性

描述

table_id

表的ID

name

表名称

match

指示表可以匹配的字段的 (1 << OFPXMT_*) 的位图

通配符

表支持的通配符 (1 << OFPXMT_*) 位图

write_actions

表支持的具有 OFPIT_WRITE_ACTIONS 的 OFPAT_* 位图

apply_actions

表支持的具有 OFPIT_APPLY_ACTIONS 的 OFPAT_* 位图

write_setfields

可以使用 OFPIT_WRITE_ACTIONS 设置的头部字段 (1 << OFPXMT_*) 位图

apply_setfields

可以使用 OFPIT_APPLY_ACTIONS 设置的头部字段 (1 << OFPXMT_*) 位图

metadata_match

表可以匹配的元数据位

metadata_write

表可以写入的元数据位

instructions

支持的 OFPIT_* 值的位图

config

OFPTC_* 值的位图

max_entries

支持的最大条目数

active_count

活动条目的数量

lookup_count

在表中查找的数据包数量

matched_count

命中表的包数量

示例

@set_ev_cls(ofp_event.EventOFPStatsReply, MAIN_DISPATCHER)
def stats_reply_handler(self, ev):
    msg = ev.msg
    ofp = msg.datapath.ofproto
    body = ev.msg.body

    if msg.type == ofp.OFPST_TABLE:
        self.table_stats_reply_handler(body)

def table_stats_reply_handler(self, body):
    tables = []
    for stat in body:
        tables.append('table_id=%d active_count=%d lookup_count=%d '
                      ' matched_count=%d' %
                      (stat.table_id, stat.active_count,
                       stat.lookup_count, stat.matched_count))
    self.logger.debug('TableStats: %s', tables)
class os_ken.ofproto.ofproto_v1_2_parser.OFPPortStatsRequest(datapath, port_no=4294967295, flags=0)

端口统计请求消息

控制器使用此消息查询端口统计信息。

属性

描述

port_no

要读取的端口号(OFPP_ANY 表示所有端口)

flags

零(规范中尚未定义)

示例

def send_port_stats_request(self, datapath):
    ofp = datapath.ofproto
    ofp_parser = datapath.ofproto_parser

    req = ofp_parser.OFPPortStatsRequest(datapath, ofp.OFPP_ANY)
    datapath.send_msg(req)

JSON 示例

{
   "OFPPortStatsRequest": {
      "flags": 0,
      "port_no": 4294967295
   }
}
class os_ken.ofproto.ofproto_v1_2_parser.OFPPortStats(port_no, rx_packets, tx_packets, rx_bytes, tx_bytes, rx_dropped, tx_dropped, rx_errors, tx_errors, rx_frame_err, rx_over_err, rx_crc_err, collisions)

端口统计回复消息

交换机用包含此消息的统计回复响应端口统计请求。

属性

描述

port_no

端口号

rx_packets

接收到的数据包数量

tx_packets

发送的数据包数量

rx_bytes

接收到的字节数

tx_bytes

发送的字节数

rx_dropped

RX 丢弃的数据包数量

tx_dropped

TX 丢弃的数据包数量

rx_errors

接收错误数量

tx_errors

发送错误数量

rx_frame_err

帧对齐错误数量

rx_over_err

具有 RX 超出错误的数据包数量

rx_crc_err

CRC 错误数量

collisions

冲突数量

示例

@set_ev_cls(ofp_event.EventOFPStatsReply, MAIN_DISPATCHER)
def stats_reply_handler(self, ev):
    msg = ev.msg
    ofp = msg.datapath.ofproto
    body = ev.msg.body

    if msg.type == ofp.OFPST_PORT:
        self.port_stats_reply_handler(body)

def port_stats_reply_handler(self, body):
    ports = []
    for stat in body:
        ports.append('port_no=%d '
                     'rx_packets=%d tx_packets=%d '
                     'rx_bytes=%d tx_bytes=%d '
                     'rx_dropped=%d tx_dropped=%d '
                     'rx_errors=%d tx_errors=%d '
                     'rx_frame_err=%d rx_over_err=%d rx_crc_err=%d '
                     'collisions=%d' %
                     (stat.port_no,
                      stat.rx_packets, stat.tx_packets,
                      stat.rx_bytes, stat.tx_bytes,
                      stat.rx_dropped, stat.tx_dropped,
                      stat.rx_errors, stat.tx_errors,
                      stat.rx_frame_err, stat.rx_over_err,
                      stat.rx_crc_err, stat.collisions))
    self.logger.debug('PortStats: %s', ports)

JSON 示例

{
   "OFPStatsReply": {
      "body": [
         {
            "OFPPortStats": {
               "collisions": 0,
               "port_no": 7,
               "rx_bytes": 0,
               "rx_crc_err": 0,
               "rx_dropped": 0,
               "rx_errors": 0,
               "rx_frame_err": 0,
               "rx_over_err": 0,
               "rx_packets": 0,
               "tx_bytes": 336,
               "tx_dropped": 0,
               "tx_errors": 0,
               "tx_packets": 4
            }
         },
         {
            "OFPPortStats": {
               "collisions": 0,
               "port_no": 6,
               "rx_bytes": 336,
               "rx_crc_err": 0,
               "rx_dropped": 0,
               "rx_errors": 0,
               "rx_frame_err": 0,
               "rx_over_err": 0,
               "rx_packets": 4,
               "tx_bytes": 336,
               "tx_dropped": 0,
               "tx_errors": 0,
               "tx_packets": 4
            }
         }
      ],
      "flags": 0,
      "type": 4
   }
}
class os_ken.ofproto.ofproto_v1_2_parser.OFPQueueStatsRequest(datapath, port_no=4294967295, queue_id=4294967295, flags=0)

队列统计请求消息

控制器使用此消息查询队列统计信息。

属性

描述

port_no

要读取的端口号

queue_id

要读取的队列 ID

flags

零(规范中尚未定义)

示例

def send_queue_stats_request(self, datapath):
    ofp = datapath.ofproto
    ofp_parser = datapath.ofproto_parser

    req = ofp_parser.OFPQueueStatsRequest(datapath, ofp.OFPP_ANY,
                                          ofp.OFPQ_ALL)
    datapath.send_msg(req)

JSON 示例

{
   "OFPQueueStatsRequest": {
      "flags": 0,
      "port_no": 4294967295,
      "queue_id": 4294967295
   }
}
class os_ken.ofproto.ofproto_v1_2_parser.OFPQueueStats(port_no, queue_id, tx_bytes, tx_packets, tx_errors)

队列统计回复消息

交换机用包含此消息的统计回复响应聚合流统计请求。

属性

描述

port_no

端口号

queue_id

队列ID

tx_bytes

发送的字节数

tx_packets

发送的数据包数量

tx_errors

由于溢出而丢弃的数据包数量

示例

@set_ev_cls(ofp_event.EventOFPStatsReply, MAIN_DISPATCHER)
def stats_reply_handler(self, ev):
    msg = ev.msg
    ofp = msg.datapath.ofproto
    body = ev.msg.body

    if msg.type == ofp.OFPST_QUEUE:
        self.queue_stats_reply_handler(body)

def queue_stats_reply_handler(self, body):
    queues = []
    for stat in body:
        queues.append('port_no=%d queue_id=%d '
                      'tx_bytes=%d tx_packets=%d tx_errors=%d ' %
                      (stat.port_no, stat.queue_id,
                       stat.tx_bytes, stat.tx_packets, stat.tx_errors))
    self.logger.debug('QueueStats: %s', queues)

JSON 示例

{
   "OFPStatsReply": {
      "body": [
         {
            "OFPQueueStats": {
               "port_no": 7,
               "queue_id": 1,
               "tx_bytes": 0,
               "tx_errors": 0,
               "tx_packets": 0
            }
         },
         {
            "OFPQueueStats": {
               "port_no": 6,
               "queue_id": 1,
               "tx_bytes": 0,
               "tx_errors": 0,
               "tx_packets": 0
            }
         },
         {
            "OFPQueueStats": {
               "port_no": 7,
               "queue_id": 2,
               "tx_bytes": 0,
               "tx_errors": 0,
               "tx_packets": 0
            }
         }
      ],
      "flags": 0,
      "type": 5
   }
}
class os_ken.ofproto.ofproto_v1_2_parser.OFPGroupStatsRequest(datapath, group_id=4294967292, flags=0)

组统计请求消息

控制器使用此消息查询一个或多个组的统计信息。

属性

描述

group_id

要读取的组ID(使用OFPG_ALL表示所有组)

flags

零(规范中尚未定义)

示例

def send_group_stats_request(self, datapath):
    ofp = datapath.ofproto
    ofp_parser = datapath.ofproto_parser

    req = ofp_parser.OFPGroupStatsRequest(datapath, ofp.OFPG_ALL)
    datapath.send_msg(req)
class os_ken.ofproto.ofproto_v1_2_parser.OFPGroupStats(group_id, ref_count, packet_count, byte_count, bucket_counters, length=None)

组统计回复消息

交换机用包含此消息的统计回复响应组统计请求。

属性

描述

group_id

组标识符

ref_count

直接转发到此组的流或组的数量

packet_count

组处理的数据包数量

byte_count

组处理的字节数

bucket_counters

OFPBucketCounter 实例列表

示例

@set_ev_cls(ofp_event.EventOFPStatsReply, MAIN_DISPATCHER)
def stats_reply_handler(self, ev):
    msg = ev.msg
    ofp = msg.datapath.ofproto
    body = ev.msg.body

    if msg.type == ofp.OFPST_GROUP:
        self.group_stats_reply_handler(body)

def group_stats_reply_handler(self, body):
    groups = []
    for stat in body:
        groups.append('group_id=%d ref_count=%d packet_count=%d '
                      'byte_count=%d bucket_counters=%s' %
                      (stat.group_id,
                       stat.ref_count, stat.packet_count,
                       stat.byte_count, stat.bucket_counters))
    self.logger.debug('GroupStats: %s', groups)
class os_ken.ofproto.ofproto_v1_2_parser.OFPGroupDescStatsRequest(datapath, flags=0)

组描述请求消息

控制器使用此消息列出交换机上的组集合。

属性

描述

flags

零(规范中尚未定义)

示例

def send_group_desc_stats_request(self, datapath):
    ofp_parser = datapath.ofproto_parser

    req = ofp_parser.OFPGroupDescStatsRequest(datapath)
    datapath.send_msg(req)

JSON 示例

{
   "OFPGroupDescStatsRequest": {
      "flags": 0
   }
}
class os_ken.ofproto.ofproto_v1_2_parser.OFPGroupDescStats(type_, group_id, buckets, length=None)

组描述回复消息

交换机用包含此消息的统计回复响应组描述请求。

属性

描述

type

OFPGT_* 中的一个

group_id

组标识符

buckets

OFPBucket 实例列表

type 属性对应于 __init__ 的 type_ 参数。

示例

@set_ev_cls(ofp_event.EventOFPStatsReply, MAIN_DISPATCHER)
def stats_reply_handler(self, ev):
    msg = ev.msg
    ofp = msg.datapath.ofproto
    body = ev.msg.body

    if msg.type == ofp.OFPST_GROUP_DESC:
        self.group_desc_stats_reply_handler(body)

def group_desc_stats_reply_handler(self, body):
    descs = []
    for stat in body:
        descs.append('type=%d group_id=%d buckets=%s' %
                     (stat.type, stat.group_id, stat.buckets))
    self.logger.debug('GroupDescStats: %s', descs)

JSON 示例

{
   "OFPStatsReply": {
      "body": [
         {
            "OFPGroupDescStats": {
               "buckets": [
                  {
                     "OFPBucket": {
                        "actions": [
                           {
                              "OFPActionOutput": {
                                 "len": 16,
                                 "max_len": 65535,
                                 "port": 2,
                                 "type": 0
                              }
                           }
                        ],
                        "len": 32,
                        "watch_group": 1,
                        "watch_port": 1,
                        "weight": 1
                     }
                  }
               ],
               "group_id": 1,
               "length": 40,
               "type": 0
            }
         }
      ],
      "flags": 0,
      "type": 7
   }
}
class os_ken.ofproto.ofproto_v1_2_parser.OFPGroupFeaturesStatsRequest(datapath, flags=0)

组功能请求消息

控制器使用此消息查询交换机上组的功能。

属性

描述

flags

零(规范中尚未定义)

示例

def send_group_features_stats_request(self, datapath):
    ofp_parser = datapath.ofproto_parser

    req = ofp_parser.OFPGroupFeaturesStatsRequest(datapath)
    datapath.send_msg(req)

JSON 示例

{
   "OFPGroupFeaturesStatsRequest": {
      "flags": 0
   }
}
class os_ken.ofproto.ofproto_v1_2_parser.OFPGroupFeaturesStats(types, capabilities, max_groups, actions, length=None)

组功能回复消息

交换机用包含此消息的统计回复响应组功能请求。

属性

描述

types

支持的 OFPGT_* 值的位图

capabilities

支持的 OFPGFC_* 功能位图

max_groups

每种类型的最大组数

动作

支持的 OFPAT_* 的位图

示例

@set_ev_cls(ofp_event.EventOFPStatsReply, MAIN_DISPATCHER)
def stats_reply_handler(self, ev):
    msg = ev.msg
    ofp = msg.datapath.ofproto
    body = ev.msg.body

    if msg.type == ofp.OFPST_GROUP_FEATURES:
        self.group_features_stats_reply_handler(body)

def group_features_stats_reply_handler(self, body):
    self.logger.debug('GroupFeaturesStats: types=%d '
                      'capabilities=0x%08x max_groups=%s '
                      'actions=%s',
                      body.types, body.capabilities, body.max_groups,
                      body.actions)

JSON 示例

{
   "OFPStatsReply": {
      "body": {
         "OFPGroupFeaturesStats": {
            "actions": [
               67082241,
               67082241,
               67082241,
               67082241
            ],
            "capabilities": 5,
            "length": 40,
            "max_groups": [
               16777216,
               16777216,
               16777216,
               16777216
            ],
            "types": 15
         }
      },
      "flags": 0,
      "type": 8
   }
}

队列配置消息

class os_ken.ofproto.ofproto_v1_2_parser.OFPQueueGetConfigRequest(datapath, port)

队列配置请求消息

属性

描述

port

要查询的端口(OFPP_ANY 到所有配置的队列)

示例

def send_queue_get_config_request(self, datapath):
    ofp = datapath.ofproto
    ofp_parser = datapath.ofproto_parser

    req = ofp_parser.OFPQueueGetConfigRequest(datapath, ofp.OFPP_ANY)
    datapath.send_msg(req)

JSON 示例

{
   "OFPQueueGetConfigRequest": {
      "port": 4294967295
   }
}
class os_ken.ofproto.ofproto_v1_2_parser.OFPQueueGetConfigReply(datapath, port=None, queues=None)

队列配置回复消息

交换机通过此消息响应队列配置请求。

属性

描述

port

查询的端口

queues

OFPPacketQueue 实例列表

示例

@set_ev_cls(ofp_event.EventOFPQueueGetConfigReply, MAIN_DISPATCHER)
def queue_get_config_reply_handler(self, ev):
    msg = ev.msg

    self.logger.debug('OFPQueueGetConfigReply received: '
                      'port=%s queues=%s',
                      msg.port, msg.queues)

JSON 示例

{
   "OFPQueueGetConfigReply": {
      "port": 4294967295,
      "queues": [
         {
            "OFPPacketQueue": {
               "len": 48,
               "port": 77,
               "properties": [
                  {
                     "OFPQueuePropMinRate": {
                        "len": 16,
                        "property": 1,
                        "rate": 10
                     }
                  },
                  {
                     "OFPQueuePropMaxRate": {
                        "len": 16,
                        "property": 2,
                        "rate": 900
                     }
                  }
               ],
               "queue_id": 99
            }
         },
         {
            "OFPPacketQueue": {
               "len": 48,
               "port": 77,
               "properties": [
                  {
                     "OFPQueuePropMinRate": {
                        "len": 16,
                        "property": 1,
                        "rate": 100
                     }
                  },
                  {
                     "OFPQueuePropMaxRate": {
                        "len": 16,
                        "property": 2,
                        "rate": 200
                     }
                  }
               ],
               "queue_id": 88
            }
         }
      ]
   }
}

报文输出消息

class os_ken.ofproto.ofproto_v1_2_parser.OFPPacketOut(datapath, buffer_id=None, in_port=None, actions=None, data=None, actions_len=None)

报文输出消息

控制器使用此消息通过交换机发送一个报文。

属性

描述

buffer_id

由数据路径分配的ID (如果没有则为 OFP_NO_BUFFER)

in_port

报文的输入端口或 OFPP_CONTROLLER

动作

OpenFlow动作类的列表

data

二进制类型值的报文数据或 packet.Packet 的实例。

示例

def send_packet_out(self, datapath, buffer_id, in_port):
    ofp = datapath.ofproto
    ofp_parser = datapath.ofproto_parser

    actions = [ofp_parser.OFPActionOutput(ofp.OFPP_FLOOD, 0)]
    req = ofp_parser.OFPPacketOut(datapath, buffer_id,
                                  in_port, actions)
    datapath.send_msg(req)

JSON 示例

{
   "OFPPacketOut": {
      "actions": [
         {
            "OFPActionOutput": {
               "len": 16,
               "max_len": 65535,
               "port": 4294967292,
               "type": 0
            }
         }
      ],
      "actions_len": 16,
      "buffer_id": 4294967295,
      "data": "8guk0D9w8gukffjqCABFAABU+BoAAP8Br4sKAAABCgAAAggAAgj3YAAAMdYCAAAAAACrjS0xAAAAABAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vAAAAAAAAAAA=",
      "in_port": 4294967293
   }
}

屏障消息

class os_ken.ofproto.ofproto_v1_2_parser.OFPBarrierRequest(datapath)

屏障请求消息

控制器发送此消息以确保已满足消息依赖关系或接收已完成操作的通知。

示例

def send_barrier_request(self, datapath):
    ofp_parser = datapath.ofproto_parser

    req = ofp_parser.OFPBarrierRequest(datapath)
    datapath.send_msg(req)

JSON 示例

{
   "OFPBarrierRequest": {}
}
class os_ken.ofproto.ofproto_v1_2_parser.OFPBarrierReply(datapath)

屏障回复消息

交换机用此消息响应屏障请求。

示例

@set_ev_cls(ofp_event.EventOFPBarrierReply, MAIN_DISPATCHER)
def barrier_reply_handler(self, ev):
    self.logger.debug('OFPBarrierReply received')

JSON 示例

{
   "OFPBarrierReply": {}
}

角色请求消息

class os_ken.ofproto.ofproto_v1_2_parser.OFPRoleRequest(datapath, role, generation_id)

角色请求消息

控制器使用此消息来更改其角色。

属性

描述

role

以下值之一。

OFPCR_ROLE_NOCHANGE
OFPCR_ROLE_EQUAL
OFPCR_ROLE_MASTER
OFPCR_ROLE_SLAVE

generation_id

主选举生成ID

示例

def send_role_request(self, datapath):
    ofp = datapath.ofproto
    ofp_parser = datapath.ofproto_parser

    req = ofp_parser.OFPRoleRequest(datapath, ofp.OFPCR_ROLE_EQUAL, 0)
    datapath.send_msg(req)

JSON 示例

{
   "OFPRoleRequest": {
      "generation_id": 17294086455919964160,
      "role": 2
   }
}
class os_ken.ofproto.ofproto_v1_2_parser.OFPRoleReply(datapath, role=None, generation_id=None)

角色回复消息

交换机用此消息响应角色请求。

属性

描述

role

以下值之一。

OFPCR_ROLE_NOCHANGE
OFPCR_ROLE_EQUAL
OFPCR_ROLE_MASTER
OFPCR_ROLE_SLAVE

generation_id

主选举生成ID

示例

@set_ev_cls(ofp_event.EventOFPRoleReply, MAIN_DISPATCHER)
def role_reply_handler(self, ev):
    msg = ev.msg
    dp = msg.datapath
    ofp = dp.ofproto

    if msg.role == ofp.OFPCR_ROLE_NOCHANGE:
        role = 'NOCHANGE'
    elif msg.role == ofp.OFPCR_ROLE_EQUAL:
        role = 'EQUAL'
    elif msg.role == ofp.OFPCR_ROLE_MASTER:
        role = 'MASTER'
    elif msg.role == ofp.OFPCR_ROLE_SLAVE:
        role = 'SLAVE'
    else:
        role = 'unknown'

    self.logger.debug('OFPRoleReply received: '
                      'role=%s generation_id=%d',
                      role, msg.generation_id)

JSON 示例

{
   "OFPRoleReply": {
      "generation_id": 17294086455919964160,
      "role": 3
   }
}

异步消息

报文输入消息

class os_ken.ofproto.ofproto_v1_2_parser.OFPPacketIn(datapath, buffer_id=None, total_len=None, reason=None, table_id=None, match=None, data=None)

报文输入消息

交换机通过此消息将接收到的报文发送给控制器。

属性

描述

buffer_id

由数据路径分配的ID

total_len

帧的完整长度

reason

发送报文的原因。

OFPR_NO_MATCH
OFPR_ACTION
OFPR_INVALID_TTL

table_id

查找表的ID

match

OFPMatch 的实例

data

以太网帧

示例

@set_ev_cls(ofp_event.EventOFPPacketIn, MAIN_DISPATCHER)
def packet_in_handler(self, ev):
    msg = ev.msg
    dp = msg.datapath
    ofp = dp.ofproto

    if msg.reason == ofp.OFPR_NO_MATCH:
        reason = 'NO MATCH'
    elif msg.reason == ofp.OFPR_ACTION:
        reason = 'ACTION'
    elif msg.reason == ofp.OFPR_INVALID_TTL:
        reason = 'INVALID TTL'
    else:
        reason = 'unknown'

    self.logger.debug('OFPPacketIn received: '
                      'buffer_id=%x total_len=%d reason=%s '
                      'table_id=%d match=%s data=%s',
                      msg.buffer_id, msg.total_len, reason,
                      msg.table_id, msg.match,
                      utils.hex_array(msg.data))

JSON 示例

{
   "OFPPacketIn": {
      "buffer_id": 2,
      "data": "////////8gukffjqCAYAAQgABgQAAfILpH346goAAAEAAAAAAAAKAAAD",
      "match": {
         "OFPMatch": {
            "length": 80,
            "oxm_fields": [
               {
                  "OXMTlv": {
                     "field": "in_port",
                     "mask": null,
                     "value": 6
                  }
               },
               {
                  "OXMTlv": {
                     "field": "eth_type",
                     "mask": null,
                     "value": 2054
                  }
               },
               {
                  "OXMTlv": {
                     "field": "eth_dst",
                     "mask": null,
                     "value": "ff:ff:ff:ff:ff:ff"
                  }
               },
               {
                  "OXMTlv": {
                     "field": "eth_src",
                     "mask": null,
                     "value": "f2:0b:a4:7d:f8:ea"
                  }
               },
               {
                  "OXMTlv": {
                     "field": "arp_op",
                     "mask": null,
                     "value": 1
                  }
               },
               {
                  "OXMTlv": {
                     "field": "arp_spa",
                     "mask": null,
                     "value": "10.0.0.1"
                  }
               },
               {
                  "OXMTlv": {
                     "field": "arp_tpa",
                     "mask": null,
                     "value": "10.0.0.3"
                  }
               },
               {
                  "OXMTlv": {
                     "field": "arp_sha",
                     "mask": null,
                     "value": "f2:0b:a4:7d:f8:ea"
                  }
               },
               {
                  "OXMTlv": {
                     "field": "arp_tha",
                     "mask": null,
                     "value": "00:00:00:00:00:00"
                  }
               }
            ],
            "type": 1
         }
      },
      "reason": 1,
      "table_id": 1,
      "total_len": 42
   }
}

流移除消息

class os_ken.ofproto.ofproto_v1_2_parser.OFPFlowRemoved(datapath, cookie=None, priority=None, reason=None, table_id=None, duration_sec=None, duration_nsec=None, idle_timeout=None, hard_timeout=None, packet_count=None, byte_count=None, match=None)

流移除消息

当流条目超时或被删除时,交换机通过此消息通知控制器。

属性

描述

cookie

不透明的控制器颁发的标识符

priority

流条目的优先级

reason

以下值之一。

OFPRR_IDLE_TIMEOUT
OFPRR_HARD_TIMEOUT
OFPRR_DELETE
OFPRR_GROUP_DELETE

table_id

表的ID

duration_sec

流存活的时间,以秒为单位

duration_nsec

超出 duration_sec 的流存活时间,以纳秒为单位

idle_timeout

原始流 mod 中的空闲超时

hard_timeout

原始流 mod 中的硬超时

packet_count

与流关联的数据包数量

byte_count

与流关联的字节数

match

OFPMatch 的实例

示例

@set_ev_cls(ofp_event.EventOFPFlowRemoved, MAIN_DISPATCHER)
def flow_removed_handler(self, ev):
    msg = ev.msg
    dp = msg.datapath
    ofp = dp.ofproto

    if msg.reason == ofp.OFPRR_IDLE_TIMEOUT:
        reason = 'IDLE TIMEOUT'
    elif msg.reason == ofp.OFPRR_HARD_TIMEOUT:
        reason = 'HARD TIMEOUT'
    elif msg.reason == ofp.OFPRR_DELETE:
        reason = 'DELETE'
    elif msg.reason == ofp.OFPRR_GROUP_DELETE:
        reason = 'GROUP DELETE'
    else:
        reason = 'unknown'

    self.logger.debug('OFPFlowRemoved received: '
                      'cookie=%d priority=%d reason=%s table_id=%d '
                      'duration_sec=%d duration_nsec=%d '
                      'idle_timeout=%d hard_timeout=%d '
                      'packet_count=%d byte_count=%d match.fields=%s',
                      msg.cookie, msg.priority, reason, msg.table_id,
                      msg.duration_sec, msg.duration_nsec,
                      msg.idle_timeout, msg.hard_timeout,
                      msg.packet_count, msg.byte_count, msg.match)

JSON 示例

{
   "OFPFlowRemoved": {
      "byte_count": 86,
      "cookie": 0,
      "duration_nsec": 48825000,
      "duration_sec": 3,
      "hard_timeout": 0,
      "idle_timeout": 3,
      "match": {
         "OFPMatch": {
            "length": 14,
            "oxm_fields": [
               {
                  "OXMTlv": {
                     "field": "eth_dst",
                     "mask": null,
                     "value": "f2:0b:a4:7d:f8:ea"
                  }
               }
            ],
            "type": 1
         }
      },
      "packet_count": 1,
      "priority": 65535,
      "reason": 0,
      "table_id": 0
   }
}

端口状态消息

class os_ken.ofproto.ofproto_v1_2_parser.OFPPortStatus(datapath, reason=None, desc=None)

端口状态消息

交换机通知控制器端口的变化。

属性

描述

reason

以下值之一。

OFPPR_ADD
OFPPR_DELETE
OFPPR_MODIFY

desc

OFPPort 的实例

示例

@set_ev_cls(ofp_event.EventOFPPortStatus, MAIN_DISPATCHER)
def port_status_handler(self, ev):
    msg = ev.msg
    dp = msg.datapath
    ofp = dp.ofproto

    if msg.reason == ofp.OFPPR_ADD:
        reason = 'ADD'
    elif msg.reason == ofp.OFPPR_DELETE:
        reason = 'DELETE'
    elif msg.reason == ofp.OFPPR_MODIFY:
        reason = 'MODIFY'
    else:
        reason = 'unknown'

    self.logger.debug('OFPPortStatus received: reason=%s desc=%s',
                      reason, msg.desc)

JSON 示例

{
   "OFPPortStatus": {
      "desc": {
         "OFPPort": {
            "advertised": 10240,
            "config": 0,
            "curr": 10248,
            "curr_speed": 5000,
            "hw_addr": "f2:0b:a4:d0:3f:70",
            "max_speed": 5000,
            "name": "\u79c1\u306e\u30dd\u30fc\u30c8",
            "peer": 10248,
            "port_no": 7,
            "state": 4,
            "supported": 10248
         }
      },
      "reason": 0
   }
}

错误消息

class os_ken.ofproto.ofproto_v1_2_parser.OFPErrorMsg(datapath, type_=None, code=None, data=None, **kwargs)

错误消息

交换机通过此消息通知控制器问题。

属性

描述

type

错误的高级类型

code

根据类型而定的详细信息

data

根据类型和代码而定的变长数据

type 属性对应于 __init__ 的 type_ 参数。

类型和代码在 os_ken.ofproto.ofproto 中定义。

类型

代码

OFPET_HELLO_FAILED

OFPHFC_*

OFPET_BAD_REQUEST

OFPBRC_*

OFPET_BAD_ACTION

OFPBAC_*

OFPET_BAD_INSTRUCTION

OFPBIC_*

OFPET_BAD_MATCH

OFPBMC_*

OFPET_FLOW_MOD_FAILED

OFPFMFC_*

OFPET_GROUP_MOD_FAILED

OFPGMFC_*

OFPET_PORT_MOD_FAILED

OFPPMFC_*

OFPET_TABLE_MOD_FAILED

OFPTMFC_*

OFPET_QUEUE_OP_FAILED

OFPQOFC_*

OFPET_SWITCH_CONFIG_FAILED

OFPSCFC_*

OFPET_ROLE_REQUEST_FAILED

OFPRRFC_*

OFPET_EXPERIMENTER

不适用

如果 type == OFPET_EXPERIMENTER,此消息还具有以下属性。

属性

描述

exp_type

实验者定义的类型

experimenter

实验者ID

示例

@set_ev_cls(ofp_event.EventOFPErrorMsg,
            [HANDSHAKE_DISPATCHER, CONFIG_DISPATCHER, MAIN_DISPATCHER])
def error_msg_handler(self, ev):
    msg = ev.msg

    self.logger.debug('OFPErrorMsg received: type=0x%02x code=0x%02x '
                      'message=%s',
                      msg.type, msg.code, utils.hex_array(msg.data))

JSON 示例

{
   "OFPErrorMsg": {
      "code": 11,
      "data": "ZnVnYWZ1Z2E=",
      "type": 2
   }
}
{
   "OFPErrorMsg": {
      "code": null,
      "data": "amlra2VuIGRhdGE=",
      "exp_type": 60000,
      "experimenter": 999999,
      "type": 65535
   }
}

对称消息

Hello

class os_ken.ofproto.ofproto_v1_2_parser.OFPHello(datapath)

Hello 消息

当连接启动时,Hello 消息在交换机和控制器之间交换。

此消息由 OSKen 框架处理,因此 OSKen 应用程序通常不需要处理此消息。

JSON 示例

{
   "OFPHello": {}
}

Echo 请求

class os_ken.ofproto.ofproto_v1_2_parser.OFPEchoRequest(datapath, data=None)

Echo 请求消息

此消息由 OSKen 框架处理,因此 OSKen 应用程序通常不需要处理此消息。

属性

描述

data

任意长度的数据

示例

def send_echo_request(self, datapath, data):
    ofp_parser = datapath.ofproto_parser

    req = ofp_parser.OFPEchoRequest(datapath, data)
    datapath.send_msg(req)

@set_ev_cls(ofp_event.EventOFPEchoRequest,
            [HANDSHAKE_DISPATCHER, CONFIG_DISPATCHER, MAIN_DISPATCHER])
def echo_request_handler(self, ev):
    self.logger.debug('OFPEchoRequest received: data=%s',
                      utils.hex_array(ev.msg.data))

JSON 示例

{
   "OFPEchoRequest": {
      "data": "aG9nZQ=="
   }
}

Echo 响应

class os_ken.ofproto.ofproto_v1_2_parser.OFPEchoReply(datapath, data=None)

Echo 响应消息

此消息由 OSKen 框架处理,因此 OSKen 应用程序通常不需要处理此消息。

属性

描述

data

任意长度的数据

示例

def send_echo_reply(self, datapath, data):
    ofp_parser = datapath.ofproto_parser

    reply = ofp_parser.OFPEchoReply(datapath, data)
    datapath.send_msg(reply)

@set_ev_cls(ofp_event.EventOFPEchoReply,
            [HANDSHAKE_DISPATCHER, CONFIG_DISPATCHER, MAIN_DISPATCHER])
def echo_reply_handler(self, ev):
    self.logger.debug('OFPEchoReply received: data=%s',
                      utils.hex_array(ev.msg.data))

JSON 示例

{
   "OFPEchoReply": {
      "data": "aG9nZQ=="
   }
}

实验者

class os_ken.ofproto.ofproto_v1_2_parser.OFPExperimenter(datapath, experimenter=None, exp_type=None, data=None)

实验者扩展消息

属性

描述

experimenter

实验者ID

exp_type

实验者定义

data

实验者定义的任意附加数据

JSON 示例

{
   "OFPExperimenter": {
      "data": "bmF6bw==",
      "exp_type": 123456789,
      "experimenter": 98765432
   }
}

端口结构

class os_ken.ofproto.ofproto_v1_2_parser.OFPPort(port_no, hw_addr, name, config, state, curr, advertised, supported, peer, curr_speed, max_speed)

端口的描述

属性

描述

port_no

端口号,它在交换机内唯一标识一个端口。

hw_addr

端口的 MAC 地址。

name

以 null 结尾的字符串,包含接口的可读名称。

config

端口配置标志的位图。

OFPPC_PORT_DOWN
OFPPC_NO_RECV
OFPPC_NO_FWD
OFPPC_NO_PACKET_IN

state

端口状态标志的位图。

OFPPS_LINK_DOWN
OFPPS_BLOCKED
OFPPS_LIVE

curr

当前功能。

advertised

端口正在广播的功能。

支持

端口支持的功能。

peer

对端广播的功能。

当前端口速率,单位为 kbps。

当前端口速率,单位为 kbps。

最大端口速率,单位为 kbps。

最大端口速率,单位为 kbps。

流匹配结构

class os_ken.ofproto.ofproto_v1_2_parser.OFPMatch(type_=None, length=None, _ordered_fields=None, **kwargs)

流匹配结构

该类是具有 compose/query API 的流匹配结构的实现。 存在新的 API 和旧的 API 以实现兼容性。 预计以后将删除旧的 API。

您可以通过关键字参数定义流匹配。以下参数可用:

参数

描述

in_port

整数 32 位

交换机输入端口

in_phy_port

整数 32 位

交换机物理输入端口

metadata

整数 64 位

在表之间传递的元数据

eth_dst

MAC 地址

以太网目标地址

eth_src

MAC 地址

以太网源地址

eth_type

整数 16 位

以太网帧类型

vlan_vid

整数 16 位

VLAN ID

vlan_pcp

整数 8 位

VLAN 优先级

ip_dscp

整数 8 位

IP DSCP(ToS 字段中的 6 位)

ip_ecn

整数 8 位

IP ECN(ToS 字段中的 2 位)

ip_proto

整数 8 位

IP 协议

ipv4_src

IPv4 地址

IPv4 源地址

ipv4_dst

IPv4 地址

IPv4 目标地址

tcp_src

整数 16 位

TCP 源端口

tcp_dst

整数 16 位

TCP 目标端口

udp_src

整数 16 位

UDP 源端口

udp_dst

整数 16 位

UDP 目标端口

sctp_src

整数 16 位

SCTP 源端口

sctp_dst

整数 16 位

SCTP 目标端口

icmpv4_type

整数 8 位

ICMP 类型

icmpv4_code

整数 8 位

ICMP 代码

arp_op

整数 16 位

ARP 操作码

arp_spa

IPv4 地址

ARP 源 IPv4 地址

arp_tpa

IPv4 地址

ARP 目标 IPv4 地址

arp_sha

MAC 地址

ARP 源硬件地址

arp_tha

MAC 地址

ARP 目标硬件地址

ipv6_src

IPv6 地址

IPv6 源地址

ipv6_dst

IPv6 地址

IPv6 目标地址

ipv6_flabel

整数 32 位

IPv6 流标签

icmpv6_type

整数 8 位

ICMPv6 类型

icmpv6_code

整数 8 位

ICMPv6 代码

ipv6_nd_target

IPv6 地址

ND 的目标地址

ipv6_nd_sll

MAC 地址

ND 的源链路层

ipv6_nd_tll

MAC 地址

ND 的目标链路层

mpls_label

整数 32 位

MPLS 标签

mpls_tc

整数 8 位

MPLS TC

pbb_uca

整数 8 位

PBB UCA 头部字段(EXT-256 ONF 扩展的旧版本)

tcp_flags

整数 16 位

TCP 标志(EXT-109 ONF 扩展)

actset_output

整数 32 位

动作集元数据中的输出端口(EXT-233 ONF 扩展)

示例

>>> # compose
>>> match = parser.OFPMatch(
...     in_port=1,
...     eth_type=0x86dd,
...     ipv6_src=('2001:db8:bd05:1d2:288a:1fc0:1:10ee',
...               'ffff:ffff:ffff:ffff::'),
...     ipv6_dst='2001:db8:bd05:1d2:288a:1fc0:1:10ee')
>>> # query
>>> if 'ipv6_src' in match:
...     print match['ipv6_src']
...
('2001:db8:bd05:1d2:288a:1fc0:1:10ee', 'ffff:ffff:ffff:ffff::')

注意

有关受支持的 Nicira 实验者匹配的列表,请参阅 os_ken.ofproto.nx_match

注意

对于 VLAN ID 匹配字段,OpenFlow 规范中定义了特殊值。

  1. 带有和不带有 VLAN 标签的数据包

    • 示例

      match = parser.OFPMatch()
      
    • 数据包匹配

      非 VLAN 标记

      MATCH

      VLAN 标记(vlan_id=3)

      MATCH

      VLAN 标记(vlan_id=5)

      MATCH

  2. 仅不带 VLAN 标签的数据包

    • 示例

      match = parser.OFPMatch(vlan_vid=0x0000)
      
    • 数据包匹配

      非 VLAN 标记

      MATCH

      VLAN 标记(vlan_id=3)

      x

      VLAN 标记(vlan_id=5)

      x

  3. 仅带有 VLAN 标签的数据包,无论其值如何

    • 示例

      match = parser.OFPMatch(vlan_vid=(0x1000, 0x1000))
      
    • 数据包匹配

      非 VLAN 标记

      x

      VLAN 标记(vlan_id=3)

      MATCH

      VLAN 标记(vlan_id=5)

      MATCH

  4. 仅带有 VLAN 标签且 VID 等于的数据包

    • 示例

      match = parser.OFPMatch(vlan_vid=(0x1000 | 3))
      
    • 数据包匹配

      非 VLAN 标记

      x

      VLAN 标记(vlan_id=3)

      MATCH

      VLAN 标记(vlan_id=5)

      x

流指令结构

class os_ken.ofproto.ofproto_v1_2_parser.OFPInstructionGotoTable(table_id, type_=None, len_=None)

转到表指令

此指令指示处理流水线中的下一个表。

属性

描述

table_id

下一个表

class os_ken.ofproto.ofproto_v1_2_parser.OFPInstructionWriteMetadata(metadata, metadata_mask, type_=None, len_=None)

写入元数据指令

此指令将掩码后的元数据值写入元数据字段。

属性

描述

metadata

要写入的元数据值

metadata_mask

元数据写入位掩码

class os_ken.ofproto.ofproto_v1_2_parser.OFPInstructionActions(type_, actions=None, len_=None)

动作指令

此指令写入/应用/清除动作。

属性

描述

type

以下值之一。

OFPIT_WRITE_ACTIONS
OFPIT_APPLY_ACTIONS
OFPIT_CLEAR_ACTIONS

动作

OpenFlow动作类的列表

type 属性对应于 __init__ 的 type_ 参数。

动作结构

class os_ken.ofproto.ofproto_v1_2_parser.OFPActionOutput(port, max_len=65509, type_=None, len_=None)

输出动作

此动作指示将数据包输出到交换机端口。

属性

描述

port

输出端口

max_len

发送到控制器的最大长度

class os_ken.ofproto.ofproto_v1_2_parser.OFPActionGroup(group_id=0, type_=None, len_=None)

组动作

此动作指示用于处理数据包的组。

属性

描述

group_id

组标识符

class os_ken.ofproto.ofproto_v1_2_parser.OFPActionSetQueue(queue_id, type_=None, len_=None)

设置队列动作

此动作设置将用于将流映射到端口上已配置队列的队列 ID。

属性

描述

queue_id

数据包的队列 ID

class os_ken.ofproto.ofproto_v1_2_parser.OFPActionSetMplsTtl(mpls_ttl, type_=None, len_=None)

设置 MPLS TTL 动作

此动作设置 MPLS TTL。

属性

描述

mpls_ttl

MPLS TTL

class os_ken.ofproto.ofproto_v1_2_parser.OFPActionDecMplsTtl(type_=None, len_=None)

减少 MPLS TTL 动作

此动作减少 MPLS TTL。

class os_ken.ofproto.ofproto_v1_2_parser.OFPActionSetNwTtl(nw_ttl, type_=None, len_=None)

设置 IP TTL 动作

此动作设置 IP TTL。

属性

描述

nw_ttl

IP TTL

class os_ken.ofproto.ofproto_v1_2_parser.OFPActionDecNwTtl(type_=None, len_=None)

减少 IP TTL 动作

此动作减少 IP TTL。

class os_ken.ofproto.ofproto_v1_2_parser.OFPActionCopyTtlOut(type_=None, len_=None)

复制 TTL Out 动作

此动作将从外层倒数第二个头部复制 TTL 到最外层头部。

class os_ken.ofproto.ofproto_v1_2_parser.OFPActionCopyTtlIn(type_=None, len_=None)

复制 TTL In 动作

此动作将从最外层头部复制 TTL 到外层倒数第二个头部。

class os_ken.ofproto.ofproto_v1_2_parser.OFPActionPushVlan(ethertype=33024, type_=None, len_=None)

推送 VLAN 动作

此动作将新的 VLAN 标签推送到数据包。

属性

描述

ethertype

以太类型。默认值为 802.1Q (0x8100)

class os_ken.ofproto.ofproto_v1_2_parser.OFPActionPushMpls(ethertype=34887, type_=None, len_=None)

推送 MPLS 动作

此动作将新的 MPLS 头部推送到数据包。

属性

描述

ethertype

以太类型

class os_ken.ofproto.ofproto_v1_2_parser.OFPActionPopVlan(type_=None, len_=None)

弹出 VLAN 动作

此动作从数据包中弹出最外层的 VLAN 标签。

class os_ken.ofproto.ofproto_v1_2_parser.OFPActionPopMpls(ethertype=2048, type_=None, len_=None)

弹出 MPLS 动作

此动作从数据包中弹出 MPLS 头部。

class os_ken.ofproto.ofproto_v1_2_parser.OFPActionSetField(field=None, **kwargs)

设置字段动作

此动作修改数据包中的头部字段。

可用的关键字集合与 OFPMatch 相同。

示例

set_field = OFPActionSetField(eth_src="00:00:00:00:00:00")
class os_ken.ofproto.ofproto_v1_2_parser.OFPActionExperimenter(experimenter, type_=None, len_=None)

实验者动作

此动作是实验者的可扩展动作。

属性

描述

experimenter

实验者ID

注意

有关受支持的 Nicira 实验者动作列表,请参阅 os_ken.ofproto.nx_actions