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_NORMALOFPC_FRAG_DROPOFPC_FRAG_REASMOFPC_FRAG_MASKOFPC_INVALID_TTL_TO_CONTROLLERmiss_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_NORMALOFPC_FRAG_DROPOFPC_FRAG_REASMOFPC_FRAG_MASKOFPC_INVALID_TTL_TO_CONTROLLERmiss_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_CONTROLLEROFPTC_TABLE_MISS_CONTINUEOFPTC_TABLE_MISS_DROPOFPTC_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_ADDOFPFC_MODIFYOFPFC_MODIFY_STRICTOFPFC_DELETEOFPFC_DELETE_STRICTidle_timeout
丢弃前的空闲时间(秒)
hard_timeout
丢弃前的最大时间(秒)
priority
流条目的优先级
buffer_id
要应用的缓冲数据包(或 OFP_NO_BUFFER)
out_port
对于
OFPFC_DELETE*命令,要求匹配的条目包含此作为输出端口out_group
对于
OFPFC_DELETE*命令,要求匹配的条目包含此作为输出组flags
以下值之一。
OFPFF_SEND_FLOW_REMOFPFF_CHECK_OVERLAPOFPFF_RESET_COUNTSmatch
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_ADDOFPGC_MODIFYOFPGC_DELETEtype
以下值之一。
OFPGT_ALLOFPGT_SELECTOFPGT_INDIRECTOFPGT_FFgroup_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
必须与
OFPSwitchFeatures的OFPPort的 hw_addr 相同的硬件地址config
配置标志的位图。
OFPPC_PORT_DOWNOFPPC_NO_RECVOFPPC_NO_FWDOFPPC_NO_PACKET_INmask
要更改的上述配置标志的位图
advertise
以下标志的位图。
OFPPF_10MB_HDOFPPF_10MB_FDOFPPF_100MB_HDOFPPF_100MB_FDOFPPF_1GB_HDOFPPF_1GB_FDOFPPF_10GB_FDOFPPF_40GB_FDOFPPF_100GB_FDOFPPF_1TB_FDOFPPF_OTHEROFPPF_COPPEROFPPF_FIBEROFPPF_AUTONEGOFPPF_PAUSEOFPPF_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_NOCHANGEOFPCR_ROLE_EQUALOFPCR_ROLE_MASTEROFPCR_ROLE_SLAVEgeneration_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_NOCHANGEOFPCR_ROLE_EQUALOFPCR_ROLE_MASTEROFPCR_ROLE_SLAVEgeneration_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_MATCHOFPR_ACTIONOFPR_INVALID_TTLtable_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_TIMEOUTOFPRR_HARD_TIMEOUTOFPRR_DELETEOFPRR_GROUP_DELETEtable_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_ADDOFPPR_DELETEOFPPR_MODIFYdesc
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_DOWNOFPPC_NO_RECVOFPPC_NO_FWDOFPPC_NO_PACKET_INstate
端口状态标志的位图。
OFPPS_LINK_DOWNOFPPS_BLOCKEDOFPPS_LIVEcurr
当前功能。
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 规范中定义了特殊值。
带有和不带有 VLAN 标签的数据包
示例
match = parser.OFPMatch()
数据包匹配
非 VLAN 标记
MATCH
VLAN 标记(vlan_id=3)
MATCH
VLAN 标记(vlan_id=5)
MATCH
仅不带 VLAN 标签的数据包
示例
match = parser.OFPMatch(vlan_vid=0x0000)
数据包匹配
非 VLAN 标记
MATCH
VLAN 标记(vlan_id=3)
x
VLAN 标记(vlan_id=5)
x
仅带有 VLAN 标签的数据包,无论其值如何
示例
match = parser.OFPMatch(vlan_vid=(0x1000, 0x1000))
数据包匹配
非 VLAN 标记
x
VLAN 标记(vlan_id=3)
MATCH
VLAN 标记(vlan_id=5)
MATCH
仅带有 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_ACTIONSOFPIT_APPLY_ACTIONSOFPIT_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。