Notepad++ 不只有語法高亮度顯示,也有語法摺疊功能,而且支持宏以及擴充基本功能的外掛模組。
可是惋惜的是Notepad++只能在Windows平臺下使用。 工做中必須使用Windows時,Notepad++是衆多程序員最喜好的文本編輯器,
在Ubuntu下是否可以使用到相同的軟件呢?
Notepadqq就是這樣一款與Notepad++很是接近的編輯器,擁有幾乎相同的功能。
sudo add-apt-repository ppa:notepadqq-team/notepadqq sudo apt-get update sudo apt-get install notepadqq
snap install --classic notepadqq
sudo apt-get remove notepadqq sudo add-apt-repository --remove ppa:notepadqq-team/notepadqq
一流的Git集成 增量差別功能可跟蹤正在編輯的文件的更改。 移動到GTK3,以及針對Linux的各類高DPI修復。 新的主題功能和塊插入支持。 支持Unicode 11.0 對代碼塊(block caret)的支持 語法高亮增長對 Clojure, D, Go, Lua 語言的支持
sudo apt remove --autoremove sublime-text
如何實現軟件定義的集線器?
經過控制器來實現集線器算法(泛洪),而後知道數據平面實現集線器操做
控制器選用Ryu,數據平面經過Mininet模擬
在控制器上編程開發集線器應用,建立實驗網絡爲驗證方案作準備
運行程序,調試程序,驗證程序
驗證成功後,優化程序
一個數據包從port1進入,會被複制,泛洪轉發到其餘全部端口發出
from ryu.base import app_manager from ryu.ofproto import ofproto_v1_3 from ryu.controller import ofp_event from ryu.controller.handler import MAIN_DISPATCHER,CONFIG_DISPATCHER from ryu.controller.handler import set_ev_cls class Hub(app_manager.RyuApp): OFP_VERSIONS = [ofproto_v1_3.OFP_VERSION] def __init__(self,*args,**kwargs): super(Hub,self).__init__(*args,**kwargs) @set_ev_cls(ofp_event.EventOFPSwitchFeatures,CONFIG_DISPATCHER) def switch_features_handler(self,ev): datapath = ev.msg.datapath ofproto = datapath.ofproto ofp_parser = datapath.ofproto_parser match = ofp_parser.OFPMatch() actions = [ofp_parser.OFPActionOutput(ofproto.OFPP_CONTROLLER,ofproto.OFPCML_NO_BUFFER)] self.add_flow(datapath,0,match,actions,"default flow entry") def add_flow(self,datapath,priority,match,actions,remind_content): ofproto = datapath.ofproto ofp_parser = datapath.ofproto_parser inst = [ofp_parser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS, actions)] mod = ofp_parser.OFPFlowMod(datapath=datapath,priority=priority, match=match,instructions=inst); print("install to datapath,"+remind_content) datapath.send_msg(mod); @set_ev_cls(ofp_event.EventOFPPacketIn,MAIN_DISPATCHER) def packet_in_handler(self,ev): msg = ev.msg datapath = msg.datapath ofproto = datapath.ofproto ofp_parser = datapath.ofproto_parser in_port = msg.match['in_port'] print("get packet in, install flow entry,and lookback parket to datapath") match = ofp_parser.OFPMatch(); actions = [ofp_parser.OFPActionOutput(ofproto.OFPP_FLOOD)] self.add_flow(datapath,1,match,actions,"hub flow entry") out = ofp_parser.OFPPacketOut(datapath=datapath,buffer_id=msg.buffer_id, in_port=in_port,actions=actions) datapath.send_msg(out);
注意:註釋可能爲你帶來很多錯誤...儘量寫兩個版本,一個不帶註釋,用於調試。一個寫註釋,用於學習,回顧
ryu-manager hub.py --verbose #進入目錄,在hub.py文件目錄下 --verbose顯示調試信息
sudo mn --topo=linear,4 --controller=remote
openvswitch交換機與Ryu控制器鏈接,控制器下發默認流表,提示信息install to datapath,default flow entry
獲取提示信息get packet in, install flow entry,and lookback parket to datapath
from ryu.base import app_manager from ryu.ofproto import ofproto_v1_3 from ryu.controller import ofp_event from ryu.controller.handler import MAIN_DISPATCHER,CONFIG_DISPATCHER from ryu.controller.handler import set_ev_cls class Hub(app_manager.RyuApp): '''明確控制器所用OpenFlow版本''' OFP_VERSIONS = [ofproto_v1_3.OFP_VERSION] def __init__(self,*args,**kwargs): super(Hub,self).__init__(*args,**kwargs) @set_ev_cls(ofp_event.EventOFPSwitchFeatures,CONFIG_DISPATCHER) def switch_features_handler(self,ev): ''' 在Ryu控制器上,咱們須要寫一個函數去處理openvswitch的鏈接 CONFIG_DISPATCHER : Version negotiated and sent features-request message ''' #對事件進行解析 datapath = ev.msg.datapath #從鏈接中獲取數據平面的datapath數據結構 ofproto = datapath.ofproto #獲取OpenFlow協議信息 ofp_parser = datapath.ofproto_parser #獲取協議解析 #解析完成 '''在鏈接創建成功之後,須要控制器下發一個默認流表 來指揮全部匹配不到交換機的數據,把他上傳到控制器上 ''' #install the table-miss flow entry match = ofp_parser.OFPMatch() #匹配域 #OFPActionOutput將數據包發送出去, #第一個參數OFPP_CONTROLLER是接收端口, #第二個是數據包在交換機上緩存buffer_id,因爲咱們將數據包所有傳送到控制器,因此不在交換機上緩存 actions = [ofp_parser.OFPActionOutput(ofproto.OFPP_CONTROLLER,ofproto.OFPCML_NO_BUFFER)] self.add_flow(datapath,0,match,actions,"default flow entry") #默認缺省流表項,設置優先級最低便可 ''' 數據平面 是由若干網元(Network Element)組成,每一個網元包含一個或多個SDN數據路徑(SDN Datapath)。 SDN Datapath是邏輯上的網絡設備,負責轉發和處理數據無控制能力, 一個SDN DataPath包含控制數據平面接口(Control Data Plane Interface,CDPI)、代理、轉發引擎(Forwarding Engine)表和處理功能(Processing Function) SDN數據面(轉發面)的關鍵技術:對數據面進行抽象建模。 ''' def add_flow(self,datapath,priority,match,actions,remind_content): '''構建流表項 : add a flow entry, install it into datapath datapath:表示給哪個邏輯設備下發流表 priority:表示優先級 match,actions:匹配域和動做 ''' #datapath屬性 ofproto = datapath.ofproto ofp_parser = datapath.ofproto_parser #在OpenFlow1.3版本中定義了instruct指令集(交換機內部的一些操做) #construct a flow msg and send it inst = [ofp_parser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS, actions)] mod = ofp_parser.OFPFlowMod(datapath=datapath,priority=priority, match=match,instructions=inst); print("install to datapath,"+remind_content) #發送出去 datapath.send_msg(mod); '''接收數據 Ryu控制器經過裝飾器去註冊監聽某些事件,去處理這些事件。 從而實現從數據平面的消息上傳到控制器,再從控制器平面到應用平面,應用程序去處理事件,再逐跳返回到openvswitch ''' '''要處理這個事件,須要先去註冊監聽他 EventOFPPacketIn: 是咱們要監聽的事件 MAIN_DISPATCHER : 是什麼狀態下,去監聽該事件---Switch-features message received and sent set-config message ''' @set_ev_cls(ofp_event.EventOFPPacketIn,MAIN_DISPATCHER) def packet_in_handler(self,ev): '''Hub集線器類,所實現的功能: 1.接收從OpenVSwitch發送過來的數據包 2.將數據包泛洪到Hub中的其餘端口中 ''' #解析數據結構 msg = ev.msg datapath = msg.datapath ofproto = datapath.ofproto ofp_parser = datapath.ofproto_parser in_port = msg.match['in_port'] #獲取源端口 print("get packet in, install flow entry,and lookback parket to datapath") match = ofp_parser.OFPMatch(); #由於咱們是將全部轉發,因此不用管匹配,填空表示所有匹配 actions = [ofp_parser.OFPActionOutput(ofproto.OFPP_FLOOD)] #注意:FLOOD是OpenFlow協議保留端口---泛洪使用 #調用add_flow,將流表項發送 ,指導後續數據包轉發 install flwo entry to avoid packet in next time self.add_flow(datapath,1,match,actions,"hub flow entry") #等級稍微比默認流表項高級 #注意:咱們將流表項下發了,可是數據包咱們此次接收的,並無處理 #就是再將控制器上的數據包,從新發送給datapath,讓他按照流表項處理 #buffer_id是這個數據包,存放在控制器中的緩衝區位置,是在事件中的buffer_id獲取 out = ofp_parser.OFPPacketOut(datapath=datapath,buffer_id=msg.buffer_id, in_port=in_port,actions=actions,data=msg.data) datapath.send_msg(out);
""" The base class for Ryu applications. RyuApp subclasses are instantiated after ryu-manager loaded all requested Ryu application modules. __init__ should call RyuApp.__init__ with the same arguments. It's illegal to send any events in __init__. The instance attribute 'name' is the name of the class used for message routing among Ryu applications. (Cf. send_event) It's set to __class__.__name__ by RyuApp.__init__. It's discouraged for subclasses to override this. """
即咱們執行ryu-manager hub.py --verbose命令開啓Ryu控制器時,而且處理了全部請求的ryu應用程序模塊,以後Hub子類就被實例化了
def __init__(self,*args,**kwargs):
super(Hub,self).__init__(*args,**kwargs)
OFP_VERSIONS = None """ A list of supported OpenFlow versions for this RyuApp. The default is all versions supported by the framework. Examples:: OFP_VERSIONS = [ofproto_v1_0.OFP_VERSION, ofproto_v1_2.OFP_VERSION] If multiple Ryu applications are loaded in the system, the intersection of their OFP_VERSIONS is used. """
# should be named something like 'observe_event' def set_ev_cls(ev_cls, dispatchers=None): """ A decorator for Ryu application to declare an event handler. Decorated method will become an event handler. ev_cls is an event class whose instances this RyuApp wants to receive. dispatchers argument specifies one of the following negotiation phases (or a list of them) for which events should be generated for this handler. Note that, in case an event changes the phase, the phase before the change is used to check the interest. .. tabularcolumns:: |l|L| =========================================== =============================== Negotiation phase Description =========================================== =============================== ryu.controller.handler.HANDSHAKE_DISPATCHER Sending and waiting for hello message ryu.controller.handler.CONFIG_DISPATCHER Version negotiated and sent features-request message ryu.controller.handler.MAIN_DISPATCHER Switch-features message received and sent set-config message ryu.controller.handler.DEAD_DISPATCHER Disconnect from the peer. Or disconnecting due to some unrecoverable errors. =========================================== =============================== """ def _set_ev_cls_dec(handler): if 'callers' not in dir(handler): handler.callers = {} for e in _listify(ev_cls): handler.callers[e] = _Caller(_listify(dispatchers), e.__module__) return handler return _set_ev_cls_dec
@set_ev_cls(ofp_event.EventOFPSwitchFeatures,CONFIG_DISPATCHER)
(1)協商階段html
=========================================== =============================== Negotiation phase Description =========================================== =============================== ryu.controller.handler.HANDSHAKE_DISPATCHER Sending and waiting for hello message ryu.controller.handler.CONFIG_DISPATCHER Version negotiated and sent features-request message ryu.controller.handler.MAIN_DISPATCHER Switch-features message received and sent set-config message ryu.controller.handler.DEAD_DISPATCHER Disconnect from the peer. Or disconnecting due to some unrecoverable errors. =========================================== ===============================
發送並等待Hello消息python
雙方經過握手消息Hello創建安全鏈接
版本協商併發送功能請求消息linux
雙方創建TLS隧道後,方法發送hello消息進行版本協商
若是協議版本協商成功,則鏈接創建。不然發送Error消息描述協商失敗緣由,並終止鏈接
交換機特徵消息接收和發送設置配置消息程序員
協商完成後,控制器和交換機之間發送Features消息,獲取交換機參數
參數包括支持的buffer數目、流表數、Actions等
控制器發送SET_CONFIG消息向交換機發送配置參數
經過GET_CONFIG消息獲得交換機修改後的配置信息
控制器與OpenFlow交換機之間,發送PACKET_OUT和PACKET_IN消息。經過PACKET_OUT中內置的LLDP包進行網絡拓撲的探測
控制器經過FLOW_MOD向控制器下發流表操做
斷開與對等方的鏈接。或者因爲一些不可恢復的錯誤而斷開鏈接算法
def set_ev_cls(ev_cls, dispatchers=None): def _set_ev_cls_dec(handler): if 'callers' not in dir(handler): handler.callers = {} for e in _listify(ev_cls): handler.callers[e] = _Caller(_listify(dispatchers), e.__module__) return handler return _set_ev_cls_dec
外部函數是用來接收事件處理函數和函數參數 內聯函數是用來
@set_ev_cls(ofp_event.EventOFPSwitchFeatures,CONFIG_DISPATCHER) def switch_features_handler(self,ev):
get ev info: <ryu.controller.ofp_event.EventOFPSwitchFeatures object at 0x7f659220f668> 就是咱們監聽的事件類實例
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__',
'msg', 'timestamp']
EVENT ofp_event->Hub EventOFPPacketIn version=0x4,
msg_type=0xa,
msg_len=0x80,
xid=0x0,
OFPPacketIn(
buffer_id=4294967295,
cookie=0,
data=b'33\xff\x9a\xd7\xb1\x1aj\xff\x9a\xd7\xb1\x86\xdd`\x00\x00\x00\x00 :\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\xff\x9a\xd7\xb1\x87\x00~f\x00\x00\x00\x00\xfe\x80\x00\x00\x00\x00\x00\x00\x18j\xff\xff\xfe\x9a\xd7\xb1\x0e\x01\x1c\xddV\xff\xb4\xd8',
match=OFPMatch(oxm_fields={'in_port': 2}),
reason=0,
table_id=0,
total_len=86)
['_TYPE', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_base_attributes', '_class_prefixes', '_class_suffixes', '_decode_value', '_encode_value', '_get_decoder', '_get_default_decoder', '_get_default_encoder', '_get_encoder', '_get_type', '_is_class', '_opt_attributes', '_reserved', '_restore_args', '_serialize_body', '_serialize_header', '_serialize_pre',
'auxiliary_id', 'buf', 'capabilities', 'cls_from_jsondict_key', 'cls_msg_type', 'datapath', 'datapath_id', 'from_jsondict', 'msg_len', 'msg_type', 'n_buffers', 'n_tables', 'obj_from_jsondict', 'parser', 'serialize', 'set_buf', 'set_classes', 'set_headers', 'set_xid', 'stringify_attrs', 'to_jsondict', 'version', 'xid']
msg所提供的方法和屬性 'auxiliary_id', 'buf', 'capabilities', 'cls_from_jsondict_key', 'cls_msg_type',
'datapath', 'datapath_id',
'from_jsondict', 'msg_len', 'msg_type', 'n_buffers', 'n_tables',
'obj_from_jsondict', 'parser', 'serialize',
'set_buf', 'set_classes', 'set_headers', 'set_xid',
'stringify_attrs', 'to_jsondict', 'version', 'xid']
<ryu.controller.controller.Datapath object at 0x7fe1560c6048>
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_close_write', '_echo_request_loop', '_ports', '_recv_loop', '_send_loop', '_send_q_sem',
'acknowledge_echo_reply', 'address', 'close', 'echo_request_interval', 'flow_format',
'id', 'is_active', 'is_reserved_port', 'max_unreplied_echo_requests', 'ofp_brick', 'ofproto', 'ofproto_parser',
'ports', 'send',
'send_barrier', 'send_delete_all_flows', 'send_flow_del', 'send_flow_mod', 'send_msg', 'send_nxt_set_flow_format', 'send_packet_out', 'send_q',
'serve', 'set_state', 'set_version', 'set_xid', 'socket', 'state', 'supported_ofp_version', 'unreplied_echo_requests', 'xid']
<module 'ryu.ofproto.ofproto_v1_3' from '/usr/local/lib/python3.6/dist-packages/ryu/ofproto/ofproto_v1_3.py'>
['DESC_STR_LEN', 'DESC_STR_LEN_STR', 'MAX_XID', 'OFPAT_COPY_TTL_IN', 'OFPAT_COPY_TTL_OUT', 'OFPAT_DEC_MPLS_TTL', 'OFPAT_DEC_NW_TTL', 'OFPAT_EXPERIMENTER', 'OFPAT_GROUP', 'OFPAT_OUTPUT', 'OFPAT_POP_MPLS', 'OFPAT_POP_PBB', 'OFPAT_POP_VLAN', 'OFPAT_PUSH_MPLS', 'OFPAT_PUSH_PBB', 'OFPAT_PUSH_VLAN', 'OFPAT_SET_FIELD', 'OFPAT_SET_MPLS_TTL', 'OFPAT_SET_NW_TTL', 'OFPAT_SET_QUEUE', 'OFPBAC_BAD_ARGUMENT', 'OFPBAC_BAD_EXPERIMENTER', 'OFPBAC_BAD_EXP_TYPE', 'OFPBAC_BAD_LEN', 'OFPBAC_BAD_OUT_GROUP', 'OFPBAC_BAD_OUT_PORT', 'OFPBAC_BAD_QUEUE', 'OFPBAC_BAD_SET_ARGUMENT', 'OFPBAC_BAD_SET_LEN', 'OFPBAC_BAD_SET_TYPE', 'OFPBAC_BAD_TAG', 'OFPBAC_BAD_TYPE', 'OFPBAC_EPERM', 'OFPBAC_MATCH_INCONSISTENT', 'OFPBAC_TOO_MANY', 'OFPBAC_UNSUPPORTED_ORDER', 'OFPBIC_BAD_EXPERIMENTER', 'OFPBIC_BAD_EXP_TYPE', 'OFPBIC_BAD_LEN', 'OFPBIC_BAD_TABLE_ID', 'OFPBIC_EPERM', 'OFPBIC_UNKNOWN_INST', 'OFPBIC_UNSUP_INST', 'OFPBIC_UNSUP_METADATA', 'OFPBIC_UNSUP_METADATA_MASK', 'OFPBMC_BAD_DL_ADDR_MASK', 'OFPBMC_BAD_FIELD', 'OFPBMC_BAD_LEN', 'OFPBMC_BAD_MASK', 'OFPBMC_BAD_NW_ADDR_MASK', 'OFPBMC_BAD_PREREQ', 'OFPBMC_BAD_TAG', 'OFPBMC_BAD_TYPE', 'OFPBMC_BAD_VALUE', 'OFPBMC_BAD_WILDCARDS', 'OFPBMC_DUP_FIELD', 'OFPBMC_EPERM', 'OFPBRC_BAD_EXPERIMENTER', 'OFPBRC_BAD_EXP_TYPE', 'OFPBRC_BAD_LEN', 'OFPBRC_BAD_MULTIPART', 'OFPBRC_BAD_PACKET', 'OFPBRC_BAD_PORT', 'OFPBRC_BAD_TABLE_ID', 'OFPBRC_BAD_TYPE', 'OFPBRC_BAD_VERSION', 'OFPBRC_BUFFER_EMPTY', 'OFPBRC_BUFFER_UNKNOWN', 'OFPBRC_EPERM', 'OFPBRC_IS_SLAVE', 'OFPBRC_MULTIPART_BUFFER_OVERFLOW', 'OFPCML_MAX', 'OFPCML_NO_BUFFER', 'OFPCR_ROLE_EQUAL', 'OFPCR_ROLE_MASTER', 'OFPCR_ROLE_NOCHANGE', 'OFPCR_ROLE_SLAVE', 'OFPC_FLOW_STATS', 'OFPC_FRAG_DROP', 'OFPC_FRAG_MASK', 'OFPC_FRAG_NORMAL', 'OFPC_FRAG_REASM', 'OFPC_GROUP_STATS', 'OFPC_IP_REASM', 'OFPC_PORT_BLOCKED', 'OFPC_PORT_STATS', 'OFPC_QUEUE_STATS', 'OFPC_TABLE_STATS', 'OFPET_BAD_ACTION', 'OFPET_BAD_INSTRUCTION', 'OFPET_BAD_MATCH', 'OFPET_BAD_REQUEST', 'OFPET_EXPERIMENTER', 'OFPET_FLOW_MOD_FAILED', 'OFPET_GROUP_MOD_FAILED', 'OFPET_HELLO_FAILED', 'OFPET_METER_MOD_FAILED', 'OFPET_PORT_MOD_FAILED', 'OFPET_QUEUE_OP_FAILED', 'OFPET_ROLE_REQUEST_FAILED', 'OFPET_SWITCH_CONFIG_FAILED', 'OFPET_TABLE_FEATURES_FAILED', 'OFPET_TABLE_MOD_FAILED', 'OFPFC_ADD', 'OFPFC_DELETE', 'OFPFC_DELETE_STRICT', 'OFPFC_MODIFY', 'OFPFC_MODIFY_STRICT', 'OFPFF_CHECK_OVERLAP', 'OFPFF_NO_BYT_COUNTS', 'OFPFF_NO_PKT_COUNTS', 'OFPFF_RESET_COUNTS', 'OFPFF_SEND_FLOW_REM', 'OFPFMFC_BAD_COMMAND', 'OFPFMFC_BAD_FLAGS', 'OFPFMFC_BAD_TABLE_ID', 'OFPFMFC_BAD_TIMEOUT', 'OFPFMFC_EPERM', 'OFPFMFC_OVERLAP', 'OFPFMFC_TABLE_FULL', 'OFPFMFC_UNKNOWN', 'OFPGC_ADD', 'OFPGC_DELETE', 'OFPGC_MODIFY', 'OFPGFC_CHAINING', 'OFPGFC_CHAINING_CHECKS', 'OFPGFC_SELECT_LIVENESS', 'OFPGFC_SELECT_WEIGHT', 'OFPGMFC_BAD_BUCKET', 'OFPGMFC_BAD_COMMAND', 'OFPGMFC_BAD_TYPE', 'OFPGMFC_BAD_WATCH', 'OFPGMFC_CHAINED_GROUP', 'OFPGMFC_CHAINING_UNSUPPORTED', 'OFPGMFC_EPERM', 'OFPGMFC_GROUP_EXISTS', 'OFPGMFC_INVALID_GROUP', 'OFPGMFC_LOOP', 'OFPGMFC_OUT_OF_BUCKETS', 'OFPGMFC_OUT_OF_GROUPS', 'OFPGMFC_UNKNOWN_GROUP', 'OFPGMFC_WATCH_UNSUPPORTED', 'OFPGMFC_WEIGHT_UNSUPPORTED', 'OFPGT_ALL', 'OFPGT_FF', 'OFPGT_INDIRECT', 'OFPGT_SELECT', 'OFPG_ALL', 'OFPG_ANY', 'OFPG_MAX', 'OFPHET_VERSIONBITMAP', 'OFPHFC_EPERM', 'OFPHFC_INCOMPATIBLE', 'OFPIEH_AUTH', 'OFPIEH_DEST', 'OFPIEH_ESP', 'OFPIEH_FRAG', 'OFPIEH_HOP', 'OFPIEH_NONEXT', 'OFPIEH_ROUTER', 'OFPIEH_UNREP', 'OFPIEH_UNSEQ', 'OFPIT_APPLY_ACTIONS', 'OFPIT_CLEAR_ACTIONS', 'OFPIT_EXPERIMENTER', 'OFPIT_GOTO_TABLE', 'OFPIT_METER', 'OFPIT_WRITE_ACTIONS', 'OFPIT_WRITE_METADATA', 'OFPMBT_DROP', 'OFPMBT_DSCP_REMARK', 'OFPMBT_EXPERIMENTER', 'OFPMC_ADD', 'OFPMC_DELETE', 'OFPMC_MODIFY', 'OFPMF_BURST', 'OFPMF_KBPS', 'OFPMF_PKTPS', 'OFPMF_STATS', 'OFPMMFC_BAD_BAND', 'OFPMMFC_BAD_BAND_VALUE', 'OFPMMFC_BAD_BURST', 'OFPMMFC_BAD_COMMAND', 'OFPMMFC_BAD_FLAGS', 'OFPMMFC_BAD_RATE', 'OFPMMFC_INVALID_METER', 'OFPMMFC_METER_EXISTS', 'OFPMMFC_OUT_OF_BANDS', 'OFPMMFC_OUT_OF_METERS', 'OFPMMFC_UNKNOWN', 'OFPMMFC_UNKNOWN_METER', 'OFPMPF_REPLY_MORE', 'OFPMPF_REQ_MORE', 'OFPMP_AGGREGATE', 'OFPMP_DESC', 'OFPMP_EXPERIMENTER', 'OFPMP_FLOW', 'OFPMP_GROUP', 'OFPMP_GROUP_DESC', 'OFPMP_GROUP_FEATURES', 'OFPMP_METER', 'OFPMP_METER_CONFIG', 'OFPMP_METER_FEATURES', 'OFPMP_PORT_DESC', 'OFPMP_PORT_STATS', 'OFPMP_QUEUE', 'OFPMP_TABLE', 'OFPMP_TABLE_FEATURES', 'OFPMT_OXM', 'OFPMT_STANDARD', 'OFPM_ALL', 'OFPM_CONTROLLER', 'OFPM_MAX', 'OFPM_SLOWPATH', 'OFPPC_NO_FWD', 'OFPPC_NO_PACKET_IN', 'OFPPC_NO_RECV', 'OFPPC_PORT_DOWN', 'OFPPF_100GB_FD', 'OFPPF_100MB_FD', 'OFPPF_100MB_HD', 'OFPPF_10GB_FD', 'OFPPF_10MB_FD', 'OFPPF_10MB_HD', 'OFPPF_1GB_FD', 'OFPPF_1GB_HD', 'OFPPF_1TB_FD', 'OFPPF_40GB_FD', 'OFPPF_AUTONEG', 'OFPPF_COPPER', 'OFPPF_FIBER', 'OFPPF_OTHER', 'OFPPF_PAUSE', 'OFPPF_PAUSE_ASYM', 'OFPPMFC_BAD_ADVERTISE', 'OFPPMFC_BAD_CONFIG', 'OFPPMFC_BAD_HW_ADDR', 'OFPPMFC_BAD_PORT', 'OFPPMFC_EPERM', 'OFPPR_ADD', 'OFPPR_DELETE', 'OFPPR_MODIFY', 'OFPPS_BLOCKED', 'OFPPS_LINK_DOWN', 'OFPPS_LIVE', 'OFPP_ALL', 'OFPP_ANY', 'OFPP_CONTROLLER', 'OFPP_FLOOD', 'OFPP_IN_PORT', 'OFPP_LOCAL', 'OFPP_MAX', 'OFPP_NORMAL', 'OFPP_TABLE', 'OFPQCFC_EPERM', 'OFPQOFC_BAD_PORT', 'OFPQOFC_BAD_QUEUE', 'OFPQOFC_EPERM', 'OFPQT_EXPERIMENTER', 'OFPQT_MAX_RATE', 'OFPQT_MIN_RATE', 'OFPQ_ALL', 'OFPRRFC_BAD_ROLE', 'OFPRRFC_STALE', 'OFPRRFC_UNSUP', 'OFPRR_DELETE', 'OFPRR_GROUP_DELETE', 'OFPRR_HARD_TIMEOUT', 'OFPRR_IDLE_TIMEOUT', 'OFPR_ACTION', 'OFPR_INVALID_TTL', 'OFPR_NO_MATCH', 'OFPSCFC_BAD_FLAGS', 'OFPSCFC_BAD_LEN', 'OFPSCFC_EPERM', 'OFPTFFC_BAD_ARGUMENT', 'OFPTFFC_BAD_LEN', 'OFPTFFC_BAD_METADATA', 'OFPTFFC_BAD_TABLE', 'OFPTFFC_BAD_TYPE', 'OFPTFFC_EPERM', 'OFPTFPT_APPLY_ACTIONS', 'OFPTFPT_APPLY_ACTIONS_MISS', 'OFPTFPT_APPLY_SETFIELD', 'OFPTFPT_APPLY_SETFIELD_MISS', 'OFPTFPT_EXPERIMENTER', 'OFPTFPT_EXPERIMENTER_MISS', 'OFPTFPT_INSTRUCTIONS', 'OFPTFPT_INSTRUCTIONS_MISS', 'OFPTFPT_MATCH', 'OFPTFPT_NEXT_TABLES', 'OFPTFPT_NEXT_TABLES_MISS', 'OFPTFPT_WILDCARDS', 'OFPTFPT_WRITE_ACTIONS', 'OFPTFPT_WRITE_ACTIONS_MISS', 'OFPTFPT_WRITE_SETFIELD', 'OFPTFPT_WRITE_SETFIELD_MISS', 'OFPTMFC_BAD_CONFIG', 'OFPTMFC_BAD_TABLE', 'OFPTMFC_EPERM', 'OFPTT_ALL', 'OFPTT_MAX', 'OFPT_BARRIER_REPLY', 'OFPT_BARRIER_REQUEST', 'OFPT_ECHO_REPLY', 'OFPT_ECHO_REQUEST', 'OFPT_ERROR', 'OFPT_EXPERIMENTER', 'OFPT_FEATURES_REPLY', 'OFPT_FEATURES_REQUEST', 'OFPT_FLOW_MOD', 'OFPT_FLOW_REMOVED', 'OFPT_GET_ASYNC_REPLY', 'OFPT_GET_ASYNC_REQUEST', 'OFPT_GET_CONFIG_REPLY', 'OFPT_GET_CONFIG_REQUEST', 'OFPT_GROUP_MOD', 'OFPT_HELLO', 'OFPT_METER_MOD', 'OFPT_MULTIPART_REPLY', 'OFPT_MULTIPART_REQUEST', 'OFPT_PACKET_IN', 'OFPT_PACKET_OUT', 'OFPT_PORT_MOD', 'OFPT_PORT_STATUS', 'OFPT_QUEUE_GET_CONFIG_REPLY', 'OFPT_QUEUE_GET_CONFIG_REQUEST', 'OFPT_ROLE_REPLY', 'OFPT_ROLE_REQUEST', 'OFPT_SET_ASYNC', 'OFPT_SET_CONFIG', 'OFPT_TABLE_MOD', 'OFPVID_NONE', 'OFPVID_PRESENT', 'OFPXMC_EXPERIMENTER', 'OFPXMC_NXM_0', 'OFPXMC_NXM_1', 'OFPXMC_OPENFLOW_BASIC', 'OFPXMT_OFB_ARP_OP', 'OFPXMT_OFB_ARP_SHA', 'OFPXMT_OFB_ARP_SPA', 'OFPXMT_OFB_ARP_THA', 'OFPXMT_OFB_ARP_TPA', 'OFPXMT_OFB_ETH_DST', 'OFPXMT_OFB_ETH_SRC', 'OFPXMT_OFB_ETH_TYPE', 'OFPXMT_OFB_ICMPV4_CODE', 'OFPXMT_OFB_ICMPV4_TYPE', 'OFPXMT_OFB_ICMPV6_CODE', 'OFPXMT_OFB_ICMPV6_TYPE', 'OFPXMT_OFB_IN_PHY_PORT', 'OFPXMT_OFB_IN_PORT', 'OFPXMT_OFB_IPV4_DST', 'OFPXMT_OFB_IPV4_SRC', 'OFPXMT_OFB_IPV6_DST', 'OFPXMT_OFB_IPV6_EXTHDR', 'OFPXMT_OFB_IPV6_FLABEL', 'OFPXMT_OFB_IPV6_ND_SLL', 'OFPXMT_OFB_IPV6_ND_TARGET', 'OFPXMT_OFB_IPV6_ND_TLL', 'OFPXMT_OFB_IPV6_SRC', 'OFPXMT_OFB_IP_DSCP', 'OFPXMT_OFB_IP_ECN', 'OFPXMT_OFB_IP_PROTO', 'OFPXMT_OFB_METADATA', 'OFPXMT_OFB_MPLS_BOS', 'OFPXMT_OFB_MPLS_LABEL', 'OFPXMT_OFB_MPLS_TC', 'OFPXMT_OFB_PBB_ISID', 'OFPXMT_OFB_SCTP_DST', 'OFPXMT_OFB_SCTP_SRC', 'OFPXMT_OFB_TCP_DST', 'OFPXMT_OFB_TCP_SRC', 'OFPXMT_OFB_TUNNEL_ID', 'OFPXMT_OFB_UDP_DST', 'OFPXMT_OFB_UDP_SRC', 'OFPXMT_OFB_VLAN_PCP', 'OFPXMT_OFB_VLAN_VID', 'OFP_ACTION_EXPERIMENTER_HEADER_PACK_STR', 'OFP_ACTION_EXPERIMENTER_HEADER_SIZE', 'OFP_ACTION_GROUP_PACK_STR', 'OFP_ACTION_GROUP_SIZE', 'OFP_ACTION_HEADER_PACK_STR', 'OFP_ACTION_HEADER_SIZE', 'OFP_ACTION_MPLS_TTL_PACK_STR', 'OFP_ACTION_MPLS_TTL_SIZE', 'OFP_ACTION_NW_TTL_PACK_STR', 'OFP_ACTION_NW_TTL_SIZE', 'OFP_ACTION_OUTPUT_PACK_STR', 'OFP_ACTION_OUTPUT_SIZE', 'OFP_ACTION_POP_MPLS_PACK_STR', 'OFP_ACTION_POP_MPLS_SIZE', 'OFP_ACTION_PUSH_PACK_STR', 'OFP_ACTION_PUSH_SIZE', 'OFP_ACTION_SET_FIELD_PACK_STR', 'OFP_ACTION_SET_FIELD_SIZE', 'OFP_ACTION_SET_QUEUE_PACK_STR', 'OFP_ACTION_SET_QUEUE_SIZE', 'OFP_AGGREGATE_STATS_REPLY_PACK_STR', 'OFP_AGGREGATE_STATS_REPLY_SIZE', 'OFP_AGGREGATE_STATS_REQUEST_0_PACK_STR', 'OFP_AGGREGATE_STATS_REQUEST_0_SIZE', 'OFP_AGGREGATE_STATS_REQUEST_PACK_STR', 'OFP_AGGREGATE_STATS_REQUEST_SIZE', 'OFP_ASYNC_CONFIG_PACK_STR', 'OFP_ASYNC_CONFIG_SIZE', 'OFP_BUCKET_COUNTER_PACK_STR', 'OFP_BUCKET_COUNTER_SIZE', 'OFP_BUCKET_PACK_STR', 'OFP_BUCKET_SIZE', 'OFP_DEFAULT_PRIORITY', 'OFP_DESC_PACK_STR', 'OFP_DESC_SIZE', 'OFP_ERROR_EXPERIMENTER_MSG_PACK_STR', 'OFP_ERROR_EXPERIMENTER_MSG_SIZE', 'OFP_ERROR_MSG_PACK_STR', 'OFP_ERROR_MSG_SIZE', 'OFP_ETH_ALEN', 'OFP_ETH_ALEN_STR', 'OFP_EXPERIMENTER_HEADER_PACK_STR', 'OFP_EXPERIMENTER_HEADER_SIZE', 'OFP_EXPERIMENTER_MULTIPART_HEADER_PACK_STR', 'OFP_EXPERIMENTER_MULTIPART_HEADER_SIZE', 'OFP_FLOW_MOD_PACK_STR', 'OFP_FLOW_MOD_PACK_STR0', 'OFP_FLOW_MOD_SIZE', 'OFP_FLOW_REMOVED_PACK_STR', 'OFP_FLOW_REMOVED_PACK_STR0', 'OFP_FLOW_REMOVED_SIZE', 'OFP_FLOW_STATS_0_PACK_STR', 'OFP_FLOW_STATS_0_SIZE', 'OFP_FLOW_STATS_PACK_STR', 'OFP_FLOW_STATS_REQUEST_0_PACK_STR', 'OFP_FLOW_STATS_REQUEST_0_SIZE', 'OFP_FLOW_STATS_REQUEST_PACK_STR', 'OFP_FLOW_STATS_REQUEST_SIZE', 'OFP_FLOW_STATS_SIZE', 'OFP_GROUP_DESC_PACK_STR', 'OFP_GROUP_DESC_SIZE', 'OFP_GROUP_DESC_STATS_PACK_STR', 'OFP_GROUP_DESC_STATS_SIZE', 'OFP_GROUP_FEATURES_PACK_STR', 'OFP_GROUP_FEATURES_SIZE', 'OFP_GROUP_MOD_PACK_STR', 'OFP_GROUP_MOD_SIZE', 'OFP_GROUP_STATS_PACK_STR', 'OFP_GROUP_STATS_REQUEST_PACK_STR', 'OFP_GROUP_STATS_REQUEST_SIZE', 'OFP_GROUP_STATS_SIZE', 'OFP_HEADER_PACK_STR', 'OFP_HEADER_SIZE', 'OFP_HELLO_ELEM_HEADER_PACK_STR', 'OFP_HELLO_ELEM_HEADER_SIZE', 'OFP_HELLO_ELEM_VERSIONBITMAP_HEADER_PACK_STR', 'OFP_HELLO_ELEM_VERSIONBITMAP_HEADER_SIZE', 'OFP_HELLO_HEADER_SIZE', 'OFP_INSTRUCTION_ACTIONS_PACK_STR', 'OFP_INSTRUCTION_ACTIONS_SIZE', 'OFP_INSTRUCTION_GOTO_TABLE_PACK_STR', 'OFP_INSTRUCTION_GOTO_TABLE_SIZE', 'OFP_INSTRUCTION_METER_PACK_STR', 'OFP_INSTRUCTION_METER_SIZE', 'OFP_INSTRUCTION_WRITE_METADATA_PACK_STR', 'OFP_INSTRUCTION_WRITE_METADATA_SIZE', 'OFP_MATCH_PACK_STR', 'OFP_MATCH_SIZE', 'OFP_MAX_PORT_NAME_LEN', 'OFP_MAX_TABLE_NAME_LEN', 'OFP_MAX_TABLE_NAME_LEN_STR', 'OFP_METER_BAND_DROP_PACK_STR', 'OFP_METER_BAND_DROP_SIZE', 'OFP_METER_BAND_DSCP_REMARK_PACK_STR', 'OFP_METER_BAND_DSCP_REMARK_SIZE', 'OFP_METER_BAND_EXPERIMENTER_PACK_STR', 'OFP_METER_BAND_EXPERIMENTER_SIZE', 'OFP_METER_BAND_HEADER_PACK_STR', 'OFP_METER_BAND_HEADER_SIZE', 'OFP_METER_BAND_STATS_PACK_STR', 'OFP_METER_BAND_STATS_SIZE', 'OFP_METER_CONFIG_PACK_STR', 'OFP_METER_CONFIG_SIZE', 'OFP_METER_FEATURES_PACK_STR', 'OFP_METER_FEATURES_SIZE', 'OFP_METER_MOD_PACK_STR', 'OFP_METER_MOD_SIZE', 'OFP_METER_MULTIPART_REQUEST_PACK_STR', 'OFP_METER_MULTIPART_REQUEST_SIZE', 'OFP_METER_STATS_PACK_STR', 'OFP_METER_STATS_SIZE', 'OFP_MULTIPART_REPLY_PACK_STR', 'OFP_MULTIPART_REPLY_SIZE', 'OFP_MULTIPART_REQUEST_PACK_STR', 'OFP_MULTIPART_REQUEST_SIZE', 'OFP_NO_BUFFER', 'OFP_OXM_EXPERIMENTER_HEADER_PACK_STR', 'OFP_OXM_EXPERIMENTER_HEADER_SIZE', 'OFP_PACKET_IN_PACK_STR', 'OFP_PACKET_IN_SIZE', 'OFP_PACKET_OUT_PACK_STR', 'OFP_PACKET_OUT_SIZE', 'OFP_PACKET_QUEUE_PACK_STR', 'OFP_PACKET_QUEUE_SIZE', 'OFP_PORT_MOD_PACK_STR', 'OFP_PORT_MOD_SIZE', 'OFP_PORT_PACK_STR', 'OFP_PORT_SIZE', 'OFP_PORT_STATS_PACK_STR', 'OFP_PORT_STATS_REQUEST_PACK_STR', 'OFP_PORT_STATS_REQUEST_SIZE', 'OFP_PORT_STATS_SIZE', 'OFP_PORT_STATUS_DESC_OFFSET', 'OFP_PORT_STATUS_PACK_STR', 'OFP_PORT_STATUS_SIZE', 'OFP_PROP_EXPERIMENTER_PACK_STR', 'OFP_PROP_EXPERIMENTER_SIZE', 'OFP_QUEUE_GET_CONFIG_REPLY_PACK_STR', 'OFP_QUEUE_GET_CONFIG_REPLY_SIZE', 'OFP_QUEUE_GET_CONFIG_REQUEST_PACK_STR', 'OFP_QUEUE_GET_CONFIG_REQUEST_SIZE', 'OFP_QUEUE_PROP_EXPERIMENTER_PACK_STR', 'OFP_QUEUE_PROP_EXPERIMENTER_SIZE', 'OFP_QUEUE_PROP_HEADER_PACK_STR', 'OFP_QUEUE_PROP_HEADER_SIZE', 'OFP_QUEUE_PROP_MAX_RATE_PACK_STR', 'OFP_QUEUE_PROP_MAX_RATE_SIZE', 'OFP_QUEUE_PROP_MIN_RATE_PACK_STR', 'OFP_QUEUE_PROP_MIN_RATE_SIZE', 'OFP_QUEUE_STATS_PACK_STR', 'OFP_QUEUE_STATS_REQUEST_PACK_STR', 'OFP_QUEUE_STATS_REQUEST_SIZE', 'OFP_QUEUE_STATS_SIZE', 'OFP_ROLE_REQUEST_PACK_STR', 'OFP_ROLE_REQUEST_SIZE', 'OFP_SWITCH_CONFIG_PACK_STR', 'OFP_SWITCH_CONFIG_SIZE', 'OFP_SWITCH_FEATURES_PACK_STR', 'OFP_SWITCH_FEATURES_SIZE', 'OFP_TABLE_FEATURES_PACK_STR', 'OFP_TABLE_FEATURES_SIZE', 'OFP_TABLE_FEATURE_PROP_ACTIONS_PACK_STR', 'OFP_TABLE_FEATURE_PROP_ACTIONS_SIZE', 'OFP_TABLE_FEATURE_PROP_INSTRUCTIONS_PACK_STR', 'OFP_TABLE_FEATURE_PROP_INSTRUCTIONS_SIZE', 'OFP_TABLE_FEATURE_PROP_NEXT_TABLES_PACK_STR', 'OFP_TABLE_FEATURE_PROP_NEXT_TABLES_SIZE', 'OFP_TABLE_FEATURE_PROP_OXM_PACK_STR', 'OFP_TABLE_FEATURE_PROP_OXM_SIZE', 'OFP_TABLE_MOD_PACK_STR', 'OFP_TABLE_MOD_SIZE', 'OFP_TABLE_STATS_PACK_STR', 'OFP_TABLE_STATS_SIZE', 'OFP_TCP_PORT', 'OFP_VERSION', 'ONFERR_DUP_INSTRUCTION', 'ONFERR_ET_ASYNC_EPERM', 'ONFERR_ET_ASYNC_INVALUD', 'ONFERR_ET_ASYNC_UNSUPPORTED', 'ONFERR_ET_BAD_FLAGS', 'ONFERR_ET_BAD_ID', 'ONFERR_ET_BAD_PRIORITY', 'ONFERR_ET_BAD_TYPE', 'ONFERR_ET_BUNDLE_CLOSED', 'ONFERR_ET_BUNDLE_EXIST', 'ONFERR_ET_BUNDLE_IN_PROGRESS', 'ONFERR_ET_CANT_SYNC', 'ONFERR_ET_EPERM', 'ONFERR_ET_FAILED', 'ONFERR_ET_MPART_REPLY_TIMEOUT', 'ONFERR_ET_MPART_REQUEST_TIMEOUT', 'ONFERR_ET_MSG_BAD_LEN', 'ONFERR_ET_MSG_BAD_XID', 'ONFERR_ET_MSG_CONFLICT', 'ONFERR_ET_MSG_TOO_MANY', 'ONFERR_ET_MSG_UNSUP', 'ONFERR_ET_OUT_OF_BUNDLES', 'ONFERR_ET_TIMEOUT', 'ONFERR_ET_UNKNOWN', 'ONFFME_ABBREV', 'ONFFME_ADDED', 'ONFFME_DELETED', 'ONFFME_MODIFIED', 'ONFFMF_ACTIONS', 'ONFFMF_ADD', 'ONFFMF_DELETE', 'ONFFMF_INITIAL', 'ONFFMF_MODIFY', 'ONFFMF_OWN', 'ONFMP_FLOW_MONITOR', 'ONFT_FLOW_MONITOR_CANCEL', 'ONFT_FLOW_MONITOR_PAUSED', 'ONFT_FLOW_MONITOR_RESUMED', 'ONF_BCT_CLOSE_REPLY', 'ONF_BCT_CLOSE_REQUEST', 'ONF_BCT_COMMIT_REPLY', 'ONF_BCT_COMMIT_REQUEST', 'ONF_BCT_DISCARD_REPLY', 'ONF_BCT_DISCARD_REQUEST', 'ONF_BCT_OPEN_REPLY', 'ONF_BCT_OPEN_REQUEST', 'ONF_BF_ATOMIC', 'ONF_BF_ORDERED', 'ONF_BUNDLE_ADD_MSG_PACK_STR', 'ONF_BUNDLE_ADD_MSG_SIZE', 'ONF_BUNDLE_CTRL_PACK_STR', 'ONF_BUNDLE_CTRL_SIZE', 'ONF_ET_BPT_EXPERIMENTER', 'ONF_ET_BUNDLE_ADD_MESSAGE', 'ONF_ET_BUNDLE_CONTROL', 'ONF_FLOW_MONITOR_REQUEST_PACK_STR', 'ONF_FLOW_MONITOR_REQUEST_SIZE', 'ONF_FLOW_UPDATE_ABBREV_PACK_STR', 'ONF_FLOW_UPDATE_ABBREV_SIZE', 'ONF_FLOW_UPDATE_FULL_PACK_STR', 'ONF_FLOW_UPDATE_FULL_SIZE', 'ONF_FLOW_UPDATE_HEADER_PACK_STR', 'ONF_FLOW_UPDATE_HEADER_SIZE', 'OXM_OF_ARP_OP', 'OXM_OF_ARP_OP_W', 'OXM_OF_ARP_SHA', 'OXM_OF_ARP_SHA_W', 'OXM_OF_ARP_SPA', 'OXM_OF_ARP_SPA_W', 'OXM_OF_ARP_THA', 'OXM_OF_ARP_THA_W', 'OXM_OF_ARP_TPA', 'OXM_OF_ARP_TPA_W', 'OXM_OF_ETH_DST', 'OXM_OF_ETH_DST_W', 'OXM_OF_ETH_SRC', 'OXM_OF_ETH_SRC_W', 'OXM_OF_ETH_TYPE', 'OXM_OF_ETH_TYPE_W', 'OXM_OF_ICMPV4_CODE', 'OXM_OF_ICMPV4_CODE_W', 'OXM_OF_ICMPV4_TYPE', 'OXM_OF_ICMPV4_TYPE_W', 'OXM_OF_ICMPV6_CODE', 'OXM_OF_ICMPV6_CODE_W', 'OXM_OF_ICMPV6_TYPE', 'OXM_OF_ICMPV6_TYPE_W', 'OXM_OF_IN_PHY_PORT', 'OXM_OF_IN_PHY_PORT_W', 'OXM_OF_IN_PORT', 'OXM_OF_IN_PORT_W', 'OXM_OF_IPV4_DST', 'OXM_OF_IPV4_DST_W', 'OXM_OF_IPV4_SRC', 'OXM_OF_IPV4_SRC_W', 'OXM_OF_IPV6_DST', 'OXM_OF_IPV6_DST_W', 'OXM_OF_IPV6_EXTHDR', 'OXM_OF_IPV6_EXTHDR_W', 'OXM_OF_IPV6_FLABEL', 'OXM_OF_IPV6_FLABEL_W', 'OXM_OF_IPV6_ND_SLL', 'OXM_OF_IPV6_ND_SLL_W', 'OXM_OF_IPV6_ND_TARGET', 'OXM_OF_IPV6_ND_TARGET_W', 'OXM_OF_IPV6_ND_TLL', 'OXM_OF_IPV6_ND_TLL_W', 'OXM_OF_IPV6_SRC', 'OXM_OF_IPV6_SRC_W', 'OXM_OF_IP_DSCP', 'OXM_OF_IP_DSCP_W', 'OXM_OF_IP_ECN', 'OXM_OF_IP_ECN_W', 'OXM_OF_IP_PROTO', 'OXM_OF_IP_PROTO_W', 'OXM_OF_METADATA', 'OXM_OF_METADATA_W', 'OXM_OF_MPLS_BOS', 'OXM_OF_MPLS_BOS_W', 'OXM_OF_MPLS_LABEL', 'OXM_OF_MPLS_LABEL_W', 'OXM_OF_MPLS_TC', 'OXM_OF_MPLS_TC_W', 'OXM_OF_PBB_ISID', 'OXM_OF_PBB_ISID_W', 'OXM_OF_SCTP_DST', 'OXM_OF_SCTP_DST_W', 'OXM_OF_SCTP_SRC', 'OXM_OF_SCTP_SRC_W', 'OXM_OF_TCP_DST', 'OXM_OF_TCP_DST_W', 'OXM_OF_TCP_SRC', 'OXM_OF_TCP_SRC_W', 'OXM_OF_TUNNEL_ID', 'OXM_OF_TUNNEL_ID_W', 'OXM_OF_UDP_DST', 'OXM_OF_UDP_DST_W', 'OXM_OF_UDP_SRC', 'OXM_OF_UDP_SRC_W', 'OXM_OF_VLAN_PCP', 'OXM_OF_VLAN_PCP_W', 'OXM_OF_VLAN_VID', 'OXM_OF_VLAN_VID_W', 'SERIAL_NUM_LEN', 'SERIAL_NUM_LEN_STR', '_OFP_AGGREGATE_STATS_REQUEST_0_PACK_STR', '_OFP_FLOW_MOD_PACK_STR0', '_OFP_FLOW_REMOVED_PACK_STR0', '_OFP_FLOW_STATS_0_PACK_STR', '_OFP_FLOW_STATS_REQUEST_0_PACK_STR', '_OFP_MATCH_PACK_STR', '_OFP_PORT_PACK_STR', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', '_oxm_field_desc', '_oxm_tlv_header', 'calcsize', 'nicira_ext', 'ofp_error_code_to_str', 'ofp_error_to_jsondict', 'ofp_error_type_to_str', 'ofp_msg_type_to_str', 'ofproto_utils', 'oxm_fields', 'oxm_from_jsondict', 'oxm_from_user', 'oxm_from_user_header', 'oxm_get_field_info_by_name', 'oxm_normalize_user', 'oxm_parse', 'oxm_parse_header', 'oxm_serialize', 'oxm_serialize_header', 'oxm_tlv_header', 'oxm_tlv_header_extract_hasmask', 'oxm_tlv_header_extract_length', 'oxm_tlv_header_w', 'oxm_to_jsondict', 'oxm_to_user', 'oxm_to_user_header', 'oxm_types', 'type_desc']
<module 'ryu.ofproto.ofproto_v1_3_parser' from '/usr/local/lib/python3.6/dist-packages/ryu/ofproto/ofproto_v1_3_parser.py'>
['Flow', 'FlowWildcards', 'LOG', 'MTArpOp', 'MTArpSha', 'MTArpSpa', 'MTArpTha', 'MTArpTpa', 'MTEthDst', 'MTEthSrc', 'MTEthType', 'MTICMPV4Code', 'MTICMPV4Type', 'MTICMPV6Code', 'MTICMPV6Type', 'MTIPDscp', 'MTIPECN', 'MTIPProto', 'MTIPV4Dst', 'MTIPV4Src', 'MTIPv6', 'MTIPv6Dst', 'MTIPv6ExtHdr', 'MTIPv6Flabel', 'MTIPv6NdSll', 'MTIPv6NdTarget', 'MTIPv6NdTll', 'MTIPv6Src', 'MTInPhyPort', 'MTInPort', 'MTMetadata', 'MTMplsBos', 'MTMplsLabel', 'MTMplsTc', 'MTPbbIsid', 'MTSCTPDst', 'MTSCTPSrc', 'MTTCPDst', 'MTTCPSrc', 'MTTunnelId', 'MTUDPDst', 'MTUDPSrc', 'MTVlanPcp', 'MTVlanVid', 'MsgBase', 'NXAction', 'NXActionBundle', 'NXActionBundleLoad', 'NXActionCT', 'NXActionCTClear', 'NXActionConjunction', 'NXActionController', 'NXActionController2', 'NXActionDecMplsTtl', 'NXActionDecNshTtl', 'NXActionDecTtl', 'NXActionDecTtlCntIds', 'NXActionEncapEther', 'NXActionEncapNsh', 'NXActionExit', 'NXActionFinTimeout', 'NXActionLearn', 'NXActionMultipath', 'NXActionNAT', 'NXActionNote', 'NXActionOutputReg', 'NXActionOutputReg2', 'NXActionOutputTrunc', 'NXActionPopMpls', 'NXActionPopQueue', 'NXActionPushMpls', 'NXActionRegLoad', 'NXActionRegLoad2', 'NXActionRegMove', 'NXActionResubmit', 'NXActionResubmitTable', 'NXActionSample', 'NXActionSample2', 'NXActionSetMplsLabel', 'NXActionSetMplsTc', 'NXActionSetMplsTtl', 'NXActionSetQueue', 'NXActionSetTunnel', 'NXActionSetTunnel64', 'NXActionStackPop', 'NXActionStackPush', 'NXActionUnknown', 'NXFlowSpecLoad', 'NXFlowSpecMatch', 'NXFlowSpecOutput', 'OFPAction', 'OFPActionCopyTtlIn', 'OFPActionCopyTtlOut', 'OFPActionDecMplsTtl', 'OFPActionDecNwTtl', 'OFPActionExperimenter', 'OFPActionExperimenterUnknown', 'OFPActionGroup', 'OFPActionHeader', 'OFPActionId', 'OFPActionOutput', 'OFPActionPopMpls', 'OFPActionPopPbb', 'OFPActionPopVlan', 'OFPActionPushMpls', 'OFPActionPushPbb', 'OFPActionPushVlan', 'OFPActionSetField', 'OFPActionSetMplsTtl', 'OFPActionSetNwTtl', 'OFPActionSetQueue', 'OFPAggregateStats', 'OFPAggregateStatsReply', 'OFPAggregateStatsRequest', 'OFPBarrierReply', 'OFPBarrierRequest', 'OFPBucket', 'OFPBucketCounter', 'OFPDescStats', 'OFPDescStatsReply', 'OFPDescStatsRequest', 'OFPEchoReply', 'OFPEchoRequest', 'OFPErrorExperimenterMsg', 'OFPErrorMsg', 'OFPExperimenter', 'OFPExperimenterMultipart', 'OFPExperimenterOxmId', 'OFPExperimenterStatsReply', 'OFPExperimenterStatsRequest', 'OFPExperimenterStatsRequestBase', 'OFPFeaturesRequest', 'OFPFlowMod', 'OFPFlowRemoved', 'OFPFlowStats', 'OFPFlowStatsReply', 'OFPFlowStatsRequest', 'OFPFlowStatsRequestBase', 'OFPGetAsyncReply', 'OFPGetAsyncRequest', 'OFPGetConfigReply', 'OFPGetConfigRequest', 'OFPGroupDescStats', 'OFPGroupDescStatsReply', 'OFPGroupDescStatsRequest', 'OFPGroupFeaturesStats', 'OFPGroupFeaturesStatsReply', 'OFPGroupFeaturesStatsRequest', 'OFPGroupMod', 'OFPGroupStats', 'OFPGroupStatsReply', 'OFPGroupStatsRequest', 'OFPHello', 'OFPHelloElemVersionBitmap', 'OFPInstruction', 'OFPInstructionActions', 'OFPInstructionGotoTable', 'OFPInstructionId', 'OFPInstructionMeter', 'OFPInstructionWriteMetadata', 'OFPMatch', 'OFPMatchField', 'OFPMeterBand', 'OFPMeterBandDrop', 'OFPMeterBandDscpRemark', 'OFPMeterBandExperimenter', 'OFPMeterBandHeader', 'OFPMeterBandStats', 'OFPMeterConfigStats', 'OFPMeterConfigStatsReply', 'OFPMeterConfigStatsRequest', 'OFPMeterFeaturesStats', 'OFPMeterFeaturesStatsReply', 'OFPMeterFeaturesStatsRequest', 'OFPMeterMod', 'OFPMeterStats', 'OFPMeterStatsReply', 'OFPMeterStatsRequest', 'OFPMultipartReply', 'OFPMultipartRequest', 'OFPOxmId', 'OFPPacketIn', 'OFPPacketOut', 'OFPPacketQueue', 'OFPPort', 'OFPPortDescStatsReply', 'OFPPortDescStatsRequest', 'OFPPortMod', 'OFPPortStats', 'OFPPortStatsReply', 'OFPPortStatsRequest', 'OFPPortStatus', 'OFPPropBase', 'OFPPropCommonExperimenter4ByteData', 'OFPPropUnknown', 'OFPQueueGetConfigReply', 'OFPQueueGetConfigRequest', 'OFPQueueProp', 'OFPQueuePropExperimenter', 'OFPQueuePropHeader', 'OFPQueuePropMaxRate', 'OFPQueuePropMinRate', 'OFPQueueStats', 'OFPQueueStatsReply', 'OFPQueueStatsRequest', 'OFPRoleReply', 'OFPRoleRequest', 'OFPSetAsync', 'OFPSetConfig', 'OFPSwitchFeatures', 'OFPTableFeatureProp', 'OFPTableFeaturePropActions', 'OFPTableFeaturePropExperimenter', 'OFPTableFeaturePropInstructions', 'OFPTableFeaturePropNextTables', 'OFPTableFeaturePropOxm', 'OFPTableFeaturePropUnknown', 'OFPTableFeaturesStats', 'OFPTableFeaturesStatsReply', 'OFPTableFeaturesStatsRequest', 'OFPTableMod', 'OFPTableStats', 'OFPTableStatsReply', 'OFPTableStatsRequest', 'ONFBundleAddMsg', 'ONFBundleCtrlMsg', 'ONFFlowMonitorRequest', 'ONFFlowMonitorStatsRequest', 'StringifyMixin', 'UINT16_MAX', 'UINT32_MAX', 'UINT64_MAX', '_MSG_PARSERS', '_NXFlowSpec', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', '_register_exp_type', '_register_parser', '_set_msg_type', '_set_stats_type', 'addrconv', 'base64', 'ether', 'exception', 'logging', 'mac', 'msg_pack_into', 'msg_parser', 'nx_actions', 'ofproto', 'ofproto_common', 'ofproto_parser', 'packet', 'six', 'struct', 'utils']
https://blog.csdn.net/Neo233/article/details/79933849編程
OFPMatch(oxm_fields={})
['_TYPE', '__class__', '__contains__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_base_attributes', '_class_prefixes', '_class_suffixes', '_composed_with_old_api', '_decode_value', '_encode_value', '_fields2', '_flow', '_get_decoder', '_get_default_decoder', '_get_default_encoder', '_get_encoder', '_get_type', '_is_class', '_opt_attributes', '_restore_args', '_wc', 'append_field', 'cls_from_jsondict_key', 'fields', 'from_jsondict', 'get', 'items', 'iteritems', 'length', 'obj_from_jsondict', 'parser', 'parser_old', 'serialize', 'serialize_old', 'set_arp_opcode', 'set_arp_sha', 'set_arp_sha_masked', 'set_arp_spa', 'set_arp_spa_masked', 'set_arp_tha', 'set_arp_tha_masked', 'set_arp_tpa', 'set_arp_tpa_masked', 'set_classes', 'set_dl_dst', 'set_dl_dst_masked', 'set_dl_src', 'set_dl_src_masked', 'set_dl_type', 'set_icmpv4_code', 'set_icmpv4_type', 'set_icmpv6_code', 'set_icmpv6_type', 'set_in_phy_port', 'set_in_port', 'set_ip_dscp', 'set_ip_ecn', 'set_ip_proto', 'set_ipv4_dst', 'set_ipv4_dst_masked', 'set_ipv4_src', 'set_ipv4_src_masked', 'set_ipv6_dst', 'set_ipv6_dst_masked', 'set_ipv6_exthdr', 'set_ipv6_exthdr_masked', 'set_ipv6_flabel', 'set_ipv6_flabel_masked', 'set_ipv6_nd_sll', 'set_ipv6_nd_target', 'set_ipv6_nd_tll', 'set_ipv6_src', 'set_ipv6_src_masked', 'set_metadata', 'set_metadata_masked', 'set_mpls_bos', 'set_mpls_label', 'set_mpls_tc', 'set_pbb_isid', 'set_pbb_isid_masked', 'set_sctp_dst', 'set_sctp_src', 'set_tcp_dst', 'set_tcp_src', 'set_tunnel_id', 'set_tunnel_id_masked', 'set_udp_dst', 'set_udp_src', 'set_vlan_pcp', 'set_vlan_vid', 'set_vlan_vid_masked', 'set_vlan_vid_none', 'stringify_attrs', 'to_jsondict', 'type']
[OFPActionOutput(len=16,max_len=65535,port=4294967293,type=0)]
['__add__', '__class__', '__contains__', '__delattr__', '__delitem__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__iadd__', '__imul__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__rmul__', '__setattr__', '__setitem__', '__sizeof__', '__str__', '__subclasshook__', 'append', 'clear', 'copy', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort']
class OFPMatch(StringifyMixin): """ Flow Match Structure This class is implementation of the flow match structure having compose/query API. There are new API and old API for compatibility. the old API is supposed to be removed later. You can define the flow match by the keyword arguments. The following arguments are available. ================ =============== ================================== Argument Value Description ================ =============== ================================== in_port Integer 32bit Switch input port in_phy_port Integer 32bit Switch physical input port metadata Integer 64bit Metadata passed between tables eth_dst MAC address Ethernet destination address eth_src MAC address Ethernet source address eth_type Integer 16bit Ethernet frame type vlan_vid Integer 16bit VLAN id vlan_pcp Integer 8bit VLAN priority ip_dscp Integer 8bit IP DSCP (6 bits in ToS field) ip_ecn Integer 8bit IP ECN (2 bits in ToS field) ip_proto Integer 8bit IP protocol ipv4_src IPv4 address IPv4 source address ipv4_dst IPv4 address IPv4 destination address tcp_src Integer 16bit TCP source port tcp_dst Integer 16bit TCP destination port udp_src Integer 16bit UDP source port udp_dst Integer 16bit UDP destination port sctp_src Integer 16bit SCTP source port sctp_dst Integer 16bit SCTP destination port icmpv4_type Integer 8bit ICMP type icmpv4_code Integer 8bit ICMP code arp_op Integer 16bit ARP opcode arp_spa IPv4 address ARP source IPv4 address arp_tpa IPv4 address ARP target IPv4 address arp_sha MAC address ARP source hardware address arp_tha MAC address ARP target hardware address ipv6_src IPv6 address IPv6 source address ipv6_dst IPv6 address IPv6 destination address ipv6_flabel Integer 32bit IPv6 Flow Label icmpv6_type Integer 8bit ICMPv6 type icmpv6_code Integer 8bit ICMPv6 code ipv6_nd_target IPv6 address Target address for ND ipv6_nd_sll MAC address Source link-layer for ND ipv6_nd_tll MAC address Target link-layer for ND mpls_label Integer 32bit MPLS label mpls_tc Integer 8bit MPLS TC mpls_bos Integer 8bit MPLS BoS bit pbb_isid Integer 24bit PBB I-SID tunnel_id Integer 64bit Logical Port Metadata ipv6_exthdr Integer 16bit IPv6 Extension Header pseudo-field pbb_uca Integer 8bit PBB UCA header field (EXT-256 Old version of ONF Extension) tcp_flags Integer 16bit TCP flags (EXT-109 ONF Extension) actset_output Integer 32bit Output port from action set metadata (EXT-233 ONF Extension) ================ =============== ================================== Example:: >>> # 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::') .. Note:: For the list of the supported Nicira experimenter matches, please refer to :ref:`ryu.ofproto.nx_match <nx_match_structures>`. .. Note:: For VLAN id match field, special values are defined in OpenFlow Spec. 1) Packets with and without a VLAN tag - Example:: match = parser.OFPMatch() - Packet Matching ====================== ===== non-VLAN-tagged MATCH VLAN-tagged(vlan_id=3) MATCH VLAN-tagged(vlan_id=5) MATCH ====================== ===== 2) Only packets without a VLAN tag - Example:: match = parser.OFPMatch(vlan_vid=0x0000) - Packet Matching ====================== ===== non-VLAN-tagged MATCH VLAN-tagged(vlan_id=3) x VLAN-tagged(vlan_id=5) x ====================== ===== 3) Only packets with a VLAN tag regardless of its value - Example:: match = parser.OFPMatch(vlan_vid=(0x1000, 0x1000)) - Packet Matching ====================== ===== non-VLAN-tagged x VLAN-tagged(vlan_id=3) MATCH VLAN-tagged(vlan_id=5) MATCH ====================== ===== 4) Only packets with VLAN tag and VID equal - Example:: match = parser.OFPMatch(vlan_vid=(0x1000 | 3)) - Packet Matching ====================== ===== non-VLAN-tagged x VLAN-tagged(vlan_id=3) MATCH VLAN-tagged(vlan_id=5) x ====================== ===== """
out = ofp_parser.OFPPacketOut(datapath=datapath,buffer_id=msg.buffer_id, in_port=in_port,actions=actions) datapath.send_msg(out);
@_set_msg_type(ofproto.OFPT_PACKET_OUT) class OFPPacketOut(MsgBase): """ Packet-Out message The controller uses this message to send a packet out throught the switch. ================ ====================================================== Attribute Description ================ ====================================================== buffer_id ID assigned by datapath (OFP_NO_BUFFER if none) in_port Packet's input port or ``OFPP_CONTROLLER`` actions list of OpenFlow action class data Packet data of a binary type value or an instances of packet.Packet. ================ ====================================================== Example:: 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) """ def __init__(self, datapath, buffer_id=None, in_port=None, actions=None, data=None, actions_len=None): assert in_port is not None super(OFPPacketOut, self).__init__(datapath) self.buffer_id = buffer_id self.in_port = in_port self.actions_len = 0 self.actions = actions self.data = data def _serialize_body(self): self.actions_len = 0 offset = ofproto.OFP_PACKET_OUT_SIZE for a in self.actions: a.serialize(self.buf, offset) offset += a.len self.actions_len += a.len if self.data is not None: assert self.buffer_id == 0xffffffff if isinstance(self.data, packet.Packet): self.data.serialize() self.buf += self.data.data else: self.buf += self.data msg_pack_into(ofproto.OFP_PACKET_OUT_PACK_STR, self.buf, ofproto.OFP_HEADER_SIZE, self.buffer_id, self.in_port, self.actions_len) @classmethod def from_jsondict(cls, dict_, decode_string=base64.b64decode, **additional_args): if isinstance(dict_['data'], dict): data = dict_.pop('data') ins = super(OFPPacketOut, cls).from_jsondict(dict_, decode_string, **additional_args) ins.data = packet.Packet.from_jsondict(data['Packet']) dict_['data'] = data else: ins = super(OFPPacketOut, cls).from_jsondict(dict_, decode_string, **additional_args) return ins
inst = [ofp_parser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS, actions)] mod = ofp_parser.OFPFlowMod(datapath=datapath,priority=priority, match=match,instructions=inst) datapath.send_msg(mod);
class OFPInstruction(StringifyMixin): _INSTRUCTION_TYPES = {} @staticmethod def register_instruction_type(types): def _register_instruction_type(cls): for type_ in types: OFPInstruction._INSTRUCTION_TYPES[type_] = cls return cls return _register_instruction_type @classmethod def parser(cls, buf, offset): (type_, len_) = struct.unpack_from('!HH', buf, offset) cls_ = cls._INSTRUCTION_TYPES.get(type_) return cls_.parser(buf, offset)
@OFPInstruction.register_instruction_type([ofproto.OFPIT_WRITE_ACTIONS, ofproto.OFPIT_APPLY_ACTIONS, ofproto.OFPIT_CLEAR_ACTIONS]) class OFPInstructionActions(OFPInstruction): """ Actions instruction This instruction writes/applies/clears the actions. ================ ====================================================== Attribute Description ================ ====================================================== type One of following values. | OFPIT_WRITE_ACTIONS | OFPIT_APPLY_ACTIONS | OFPIT_CLEAR_ACTIONS actions list of OpenFlow action class ================ ====================================================== ``type`` attribute corresponds to ``type_`` parameter of __init__. """ def __init__(self, type_, actions=None, len_=None): super(OFPInstructionActions, self).__init__() self.type = type_ for a in actions: assert isinstance(a, OFPAction) self.actions = actions @classmethod def parser(cls, buf, offset): (type_, len_) = struct.unpack_from( ofproto.OFP_INSTRUCTION_ACTIONS_PACK_STR, buf, offset) offset += ofproto.OFP_INSTRUCTION_ACTIONS_SIZE actions = [] actions_len = len_ - ofproto.OFP_INSTRUCTION_ACTIONS_SIZE exc = None try: while actions_len > 0: a = OFPAction.parser(buf, offset) actions.append(a) actions_len -= a.len offset += a.len except struct.error as e: exc = e inst = cls(type_, actions) inst.len = len_ if exc is not None: raise exception.OFPTruncatedMessage(ofpmsg=inst, residue=buf[offset:], original_exception=exc) return inst def serialize(self, buf, offset): action_offset = offset + ofproto.OFP_INSTRUCTION_ACTIONS_SIZE if self.actions: for a in self.actions: a.serialize(buf, action_offset) action_offset += a.len self.len = action_offset - offset pad_len = utils.round_up(self.len, 8) - self.len msg_pack_into("%dx" % pad_len, buf, action_offset) self.len += pad_len msg_pack_into(ofproto.OFP_INSTRUCTION_ACTIONS_PACK_STR, buf, offset, self.type, self.len)
@_register_parser
@_set_msg_type(ofproto.OFPT_FLOW_MOD)
class OFPFlowMod(MsgBase): """ Modify Flow entry message The controller sends this message to modify the flow table. ================ ====================================================== Attribute Description ================ ====================================================== cookie Opaque controller-issued identifier cookie_mask Mask used to restrict the cookie bits that must match when the command is ``OPFFC_MODIFY*`` or ``OFPFC_DELETE*`` table_id ID of the table to put the flow in command One of the following values. | OFPFC_ADD | OFPFC_MODIFY | OFPFC_MODIFY_STRICT | OFPFC_DELETE | OFPFC_DELETE_STRICT idle_timeout Idle time before discarding (seconds) hard_timeout Max time before discarding (seconds) priority Priority level of flow entry buffer_id Buffered packet to apply to (or OFP_NO_BUFFER) out_port For ``OFPFC_DELETE*`` commands, require matching entries to include this as an output port out_group For ``OFPFC_DELETE*`` commands, require matching entries to include this as an output group flags Bitmap of the following flags. | OFPFF_SEND_FLOW_REM | OFPFF_CHECK_OVERLAP | OFPFF_RESET_COUNTS | OFPFF_NO_PKT_COUNTS | OFPFF_NO_BYT_COUNTS match Instance of ``OFPMatch`` instructions list of ``OFPInstruction*`` instance ================ ====================================================== Example:: 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) """ def __init__(self, datapath, cookie=0, cookie_mask=0, table_id=0, command=ofproto.OFPFC_ADD, idle_timeout=0, hard_timeout=0, priority=ofproto.OFP_DEFAULT_PRIORITY, buffer_id=ofproto.OFP_NO_BUFFER, out_port=0, out_group=0, flags=0, match=None, instructions=None): instructions = instructions if instructions else [] super(OFPFlowMod, self).__init__(datapath) self.cookie = cookie self.cookie_mask = cookie_mask self.table_id = table_id self.command = command self.idle_timeout = idle_timeout self.hard_timeout = hard_timeout self.priority = priority self.buffer_id = buffer_id self.out_port = out_port self.out_group = out_group self.flags = flags if match is None: match = OFPMatch() assert isinstance(match, OFPMatch) self.match = match for i in instructions: assert isinstance(i, OFPInstruction) self.instructions = instructions def _serialize_body(self): msg_pack_into(ofproto.OFP_FLOW_MOD_PACK_STR0, self.buf, ofproto.OFP_HEADER_SIZE, self.cookie, self.cookie_mask, self.table_id, self.command, self.idle_timeout, self.hard_timeout, self.priority, self.buffer_id, self.out_port, self.out_group, self.flags) offset = (ofproto.OFP_FLOW_MOD_SIZE - ofproto.OFP_MATCH_SIZE) match_len = self.match.serialize(self.buf, offset) offset += match_len for inst in self.instructions: inst.serialize(self.buf, offset) offset += inst.len @classmethod def parser(cls, datapath, version, msg_type, msg_len, xid, buf): msg = super(OFPFlowMod, cls).parser( datapath, version, msg_type, msg_len, xid, buf) (msg.cookie, msg.cookie_mask, msg.table_id, msg.command, msg.idle_timeout, msg.hard_timeout, msg.priority, msg.buffer_id, msg.out_port, msg.out_group, msg.flags) = struct.unpack_from( ofproto.OFP_FLOW_MOD_PACK_STR0, msg.buf, ofproto.OFP_HEADER_SIZE) offset = ofproto.OFP_FLOW_MOD_SIZE - ofproto.OFP_HEADER_SIZE try: msg.match = OFPMatch.parser(buf, offset) except exception.OFPTruncatedMessage as e: msg.match = e.ofpmsg e.ofpmsg = msg raise e offset += utils.round_up(msg.match.length, 8) instructions = [] try: while offset < msg_len: i = OFPInstruction.parser(buf, offset) instructions.append(i) offset += i.len except exception.OFPTruncatedMessage as e: instructions.append(e.ofpmsg) msg.instructions = instructions e.ofpmsg = msg raise e except struct.error as e: msg.instructions = instructions raise exception.OFPTruncatedMessage(ofpmsg=msg, residue=buf[offset:], original_exception=e) msg.instructions = instructions return msg
@OFPAction.register_action_type(ofproto.OFPAT_OUTPUT,
ofproto.OFP_ACTION_OUTPUT_SIZE)
class OFPActionOutput(OFPAction): """ Output action This action indicates output a packet to the switch port. ================ ====================================================== Attribute Description ================ ====================================================== port Output port max_len Max length to send to controller ================ ====================================================== """ def __init__(self, port, max_len=ofproto.OFPCML_MAX, type_=None, len_=None): super(OFPActionOutput, self).__init__() self.port = port self.max_len = max_len @classmethod def parser(cls, buf, offset): type_, len_, port, max_len = struct.unpack_from( ofproto.OFP_ACTION_OUTPUT_PACK_STR, buf, offset) return cls(port, max_len) def serialize(self, buf, offset): msg_pack_into(ofproto.OFP_ACTION_OUTPUT_PACK_STR, buf, offset, self.type, self.len, self.port, self.max_len)
<module 'ryu.ofproto.ofproto_v1_3' from '/usr/local/lib/python3.6/dist-packages/ryu/ofproto/ofproto_v1_3.py'>
# enum ofp_port_no OFPP_MAX = 0xffffff00 OFPP_IN_PORT = 0xfffffff8 # Send the packet out the input port. This # virtual port must be explicitly used # in order to send back out of the input # port. OFPP_TABLE = 0xfffffff9 # Perform actions in flow table. # NB: This can only be the destination # port for packet-out messages. OFPP_NORMAL = 0xfffffffa # Process with normal L2/L3 switching. OFPP_FLOOD = 0xfffffffb # All physical ports except input port and # those disabled by STP. OFPP_ALL = 0xfffffffc # All physical ports except input port. OFPP_CONTROLLER = 0xfffffffd # Send to controller. 這是讓交換機將數據包發送給控制器《重點》 OFPP_LOCAL = 0xfffffffe # Local openflow "port". OFPP_ANY = 0xffffffff # Not associated with a physical port.
actions = [ofp_parser.OFPActionOutput(ofproto.OFPP_CONTROLLER,ofproto.OFPCML_NO_BUFFER)] 流表項動做表示將數據包發送給控制器
# enum ofp_controller_max_len OFPCML_MAX = 0xffe5 # maximum max_len value which can be used to 可用於請求特定字節長度的最大Max值。(是向控制器請求的最大數據長度) # request a specific byte length. OFPCML_NO_BUFFER = 0xffff # indicates that no buffering should be 指示不該應用緩衝,而且將整個數據包發送到控制器 # applied and the whole packet is to be # sent to the controller.
actions = [ofp_parser.OFPActionOutput(ofproto.OFPP_CONTROLLER,ofproto.OFPCML_NO_BUFFER)] 表示交換機中不用緩存數據包,所有發送給控制器便可
NAME = 'ofp_event' class EventOFPMsgBase(event.EventBase): """ The base class of OpenFlow event class. OpenFlow event classes have at least the following attributes. .. tabularcolumns:: |l|L| ============ ============================================================== Attribute Description ============ ============================================================== msg An object which describes the corresponding OpenFlow message. msg.datapath A ryu.controller.controller.Datapath instance which describes an OpenFlow switch from which we received this OpenFlow message. timestamp Timestamp when Datapath instance generated this event. ============ ============================================================== The msg object has some more additional members whose values are extracted from the original OpenFlow message. """ def __init__(self, msg): self.timestamp = time.time() super(EventOFPMsgBase, self).__init__() self.msg = msg # # Create ofp_event type corresponding to OFP Msg # _OFP_MSG_EVENTS = {} def _ofp_msg_name_to_ev_name(msg_name): return 'Event' + msg_name def ofp_msg_to_ev(msg): return ofp_msg_to_ev_cls(msg.__class__)(msg) def ofp_msg_to_ev_cls(msg_cls): name = _ofp_msg_name_to_ev_name(msg_cls.__name__) return _OFP_MSG_EVENTS[name] def _create_ofp_msg_ev_class(msg_cls): name = _ofp_msg_name_to_ev_name(msg_cls.__name__) # print 'creating ofp_event %s' % name if name in _OFP_MSG_EVENTS: return cls = type(name, (EventOFPMsgBase,), dict(__init__=lambda self, msg: super(self.__class__, self).__init__(msg))) globals()[name] = cls _OFP_MSG_EVENTS[name] = cls def _create_ofp_msg_ev_from_module(ofp_parser): # print mod for _k, cls in inspect.getmembers(ofp_parser, inspect.isclass): if not hasattr(cls, 'cls_msg_type'): continue _create_ofp_msg_ev_class(cls) for ofp_mods in ofproto.get_ofp_modules().values(): ofp_parser = ofp_mods[1] # print 'loading module %s' % ofp_parser _create_ofp_msg_ev_from_module(ofp_parser)