OpenFlowJ-Loxigen - OFType

OpenFlowJ-Loxigen - OFType

2/26/2017 11:07:29 PM

最近在學習使用Floodlight,OpenFlowJ-Loxigen是Floodlight中對OpenFlow協議的一個抽象層。它是用Java語言實現的,爲上層應用提供了通用的和根據版本制定的Java API,爲控制器與交換機之間的信息交換和控制提供易於使用的接口。本篇博文主要用於學習OpenFlowJ-Loxigen時的知識梳理,和之前或之後的其他系列的博文一樣,會以流水賬的形式記錄知識點。因此,本博文的知識覆蓋面一般不會很全面,需要全面瞭解OpenFlowJ-Loxigen的同學,可以進入官網查閱OpenFlowJ-Loxigen的Java Doc

2017-2-28

本來準備只寫一個簡單的對該枚舉量的介紹,然而沒有想到居然扯到OpenFlowJ-Loxigen是如何對不同版本的OFType進行封裝了。因爲暫時要查閱一些資料,所以明後日再更(2017-3-2之前),感興趣的同學敬請期待。

2017-3-2

晚上有算法討論,時間有點緊,今天暫不更新了…


OFType是OpenFlowJ-Loxigen中的一個枚舉量,官方文庫中的類型聲明爲:

Enum OFType

該枚舉量中的元素如下表所示,我們可以看到OFType中所包含的元素超過了20個,但我們在開發時並不一定每個都需要用到。官方文檔中給出了元素的名稱,但沒有給出每個元素的詳細介紹,而這則是OpenFlow協議的內容。然後,問題來了,OpenFlow經歷了多個版本,這些元素又支持哪些版本呢。官方的說法是OpenFlowJ-Loxigen目前支持OpenFlow的版本爲1.0,1.1,1.2,1.3,1.4 ,那麼OFType是否可以通用呢,我們可以查看一下幾個常用的元素在不同版本的OpenFlow協議中的定義(1.0,1.3):

元素名稱 含義
HELLO——————– 1.0:Hello messages are exchanged between the switch and controller upon connection startup.
1.3:Hello messages are exchanged between the switch and controller upon connection startup
ERROR
ECHO_REQUEST
ECHO_REPLY
EXPERIMENTER
FEATURES_REQUEST
FEATURES_REPLY
GET_CONFIG_REQUEST
GET_CONFIG_REPLY
SET_CONFIG
PACKET_IN
1.0:For all packets that do not have a matching flow entry, a packet-in event is sent to the controller (or if a packet matches an entry with a \send to controller” action). If the switch has sufficient memory to buffer packets that are sent to the controller, the packet-in events contain some fraction of the packet header (by default 128 bytes) and a buffer ID to be used by the controller when it is ready for the switch to forward the packet. Switches that do not support internal buffering (or have run out of internal buffering) must send the full packet to the controller as part of the event.
1.3:Transfer the control of a packet to the controller. For all packets forwarded to the CONTROLLER reserved port using a flow entry or the table-miss flow entry, a packet-in event is always sent to controllers (see 5.12). Other processing, such as TTL checking, may also send packets to the controller using packet-in events.
Packet-in events can be configured to buffer packets. For packet-in generated by an output action in a flow entries or group bucket, it can be specified individually in the output action itself (see A.2.5), for other packet-in it can be configured in the switch configuration (see A.3.2). If the packet-in event is configured to buffer packets and the switch has sufficient memory to buffer them, the packet-in events contain only some fraction of the packet header and a buffer ID to be used by a controller when it is ready for the switch to forward the packet. Switches that do not support internal buffering, are configured to not buffer packets for the packet-in event, or have run out of internal buffering, must send the full packet to controllers as part of the event. Buffered packets will usually be processed via a Packet-out message from a controller, or automatically expired after some time.
If the packet is buffered, the number of bytes of the original packet to include in the packet-in can be configured. By default, it is 128 bytes. For packet-in generated by an output action in a flow entries or group bucket, it can be specified individually in the output action itself (see A.2.5), for other packet-in it can be configured in the switch configuration (see A.3.2).
FLOW_REMOVED 1.0:When a flow entry is added to the switch by a flow modify message, an idle timeout value indicates when the entry should be removed due to a lack of activity, as well as a hard timeout value that indicates when the entry should be removed, regardless of activity. The flow modify message also specifies whether the switch should send a flow removed message to the controller when the flow expires. Flow modify messages which delete flows may also cause flow removed messages.
1.3:Inform the controller about the removal of a flow entry from a flow table. FlowRemoved messages are only sent for flow entries with the OFPFF_SEND_FLOW_REM flag set. They are generated as the result of a controller flow delete requests or the switch flow expiry process when one of the flow timeout is exceeded (see 5.5)
PORT_STATUS
PACKET_OUT 1.0:這裏在OpenFlow Protocol Overview中提到的是Send-Packet,原文:These are used by the controller to send packets out of a specified port on the switch.
1.3:These are used by the controller to send packets out of a specified port on the switch, and to forward packets received via Packet-in messages. Packet-out messages must contain a full packet or a buffer ID referencing a packet stored in the switch. The message must also contain a list of actions to be applied in the order they are specified; an empty action list drops the packet.
FLOW_MOD 1.0:Modify-State messages are sent by the controller to manage state on the switches. Their primary purpose is to add/delete and modify flows in the flow tables and to set switch port properties.
1.3:Modify-State messages are sent by the controller to manage state on the switches. Their primary purpose is to add, delete and modify flow/group entries in the OpenFlow tables and to set switch port properties.
PORT_MOD
STATS_REQUEST
STATS_REPLY
BARRIER_REQUEST
BARRIER_REPLY
QUEUE_GET_CONFIG_REQUEST
QUEUE_GET_CONFIG_REPLY
GROUP_MOD
TABLE_MOD
ROLE_REQUEST
ROLE_REPLY
GET_ASYNC_REQUEST
GET_ASYNC_REPLY
SET_ASYNC
METER_MOD
ROLE_STATUS
TABLE_STATUS
REQUESTFORWARD
BUNDLE_CONTROL
BUNDLE_ADD_MESSAGE

上面表格中的內容取自OpenFlow Protocol Overview。OpenFlow Protocol Overview中對OpenFlow協議支持的三種message的類型和不同message類型下的子類型進行了簡單介紹(三種message類型:controller-to-switch, asynchronous, and symmetric)。所以FLOW_MOD的含義其實我是摘抄的Controller-to-Switch中Modify-State的定義,而FLOW_MOD則是Modify-State的一個子類。這之後我本來是打算比較不同版本的具體細節,如PACKET_IN,FLOW_REMOVED以及FLOW_MOD這三個消息的具體定義。但是我發現OpenFlow中也定義了OFType(原諒我,我也是個新手)。所以我們先來比較一下,OpenFlow中對OFType的定義和OpenFlowJ-Loxigen中的定義吧:

v1.0

enum ofp_type {
/* Immutable messages. */
OFPT_HELLO, /* Symmetric message */
OFPT_ERROR, /* Symmetric message */
OFPT_ECHO_REQUEST, /* Symmetric message */
OFPT_ECHO_REPLY, /* Symmetric message */
OFPT_VENDOR, /* Symmetric message */
/* Switch configuration messages. */
OFPT_FEATURES_REQUEST, /* Controller/switch message */
OFPT_FEATURES_REPLY, /* Controller/switch message */
OFPT_GET_CONFIG_REQUEST, /* Controller/switch message */
OFPT_GET_CONFIG_REPLY, /* Controller/switch message */
OFPT_SET_CONFIG, /* Controller/switch message */
/* Asynchronous messages. */
OFPT_PACKET_IN, /* Async message */
OFPT_FLOW_REMOVED, /* Async message */
OFPT_PORT_STATUS, /* Async message */
/* Controller command messages. */
OFPT_PACKET_OUT, /* Controller/switch message */
OFPT_FLOW_MOD, /* Controller/switch message */
OFPT_PORT_MOD, /* Controller/switch message */
/* Statistics messages. */
OFPT_STATS_REQUEST, /* Controller/switch message */
OFPT_STATS_REPLY, /* Controller/switch message */
/* Barrier messages. */
OFPT_BARRIER_REQUEST, /* Controller/switch message */
OFPT_BARRIER_REPLY, /* Controller/switch message */
/* Queue Configuration messages. */
OFPT_QUEUE_GET_CONFIG_REQUEST, /* Controller/switch message */
OFPT_QUEUE_GET_CONFIG_REPLY /* Controller/switch message */
};

v1.3

enum ofp_type {
/* Immutable messages. */
OFPT_HELLO = 0, /* Symmetric message */
OFPT_ERROR = 1, /* Symmetric message */
OFPT_ECHO_REQUEST = 2, /* Symmetric message */
OFPT_ECHO_REPLY = 3, /* Symmetric message */
OFPT_EXPERIMENTER = 4, /* Symmetric message */
/* Switch configuration messages. */
OFPT_FEATURES_REQUEST = 5, /* Controller/switch message */
OFPT_FEATURES_REPLY = 6, /* Controller/switch message */
OFPT_GET_CONFIG_REQUEST = 7, /* Controller/switch message */
OFPT_GET_CONFIG_REPLY = 8, /* Controller/switch message */
OFPT_SET_CONFIG = 9, /* Controller/switch message */
/* Asynchronous messages. */
OFPT_PACKET_IN = 10, /* Async message */
OFPT_FLOW_REMOVED = 11, /* Async message */
OFPT_PORT_STATUS = 12, /* Async message */
/* Controller command messages. */
OFPT_PACKET_OUT = 13, /* Controller/switch message */
OFPT_FLOW_MOD = 14, /* Controller/switch message */
OFPT_GROUP_MOD = 15, /* Controller/switch message */
OFPT_PORT_MOD = 16, /* Controller/switch message */
OFPT_TABLE_MOD = 17, /* Controller/switch message */
/* Multipart messages. */
OFPT_MULTIPART_REQUEST = 18, /* Controller/switch message */
OFPT_MULTIPART_REPLY = 19, /* Controller/switch message */
/* Barrier messages. */
OFPT_BARRIER_REQUEST = 20, /* Controller/switch message */
OFPT_BARRIER_REPLY = 21, /* Controller/switch message */
/* Queue Configuration messages. */
OFPT_QUEUE_GET_CONFIG_REQUEST = 22, /* Controller/switch message */
OFPT_QUEUE_GET_CONFIG_REPLY = 23, /* Controller/switch message */
/* Controller role change request messages. */
OFPT_ROLE_REQUEST = 24, /* Controller/switch message */
OFPT_ROLE_REPLY = 25, /* Controller/switch message */
/* Asynchronous message configuration. */
OFPT_GET_ASYNC_REQUEST = 26, /* Controller/switch message */
OFPT_GET_ASYNC_REPLY = 27, /* Controller/switch message */
OFPT_SET_ASYNC = 28, /* Controller/switch message */
/* Meters and rate limiters configuration messages. */
OFPT_METER_MOD = 29, /* Controller/switch message */
};

簡單的比較,我們會發現1.3的版本還是與1.0的版本有很大的不同的,那麼OpenFlowJ-Loxigen是如何處理不同版本之間的差異的呢?

敬請期待。

當我們比較一個協議的不同版本的時候,當然需要比較不同版本的具體細節。下面我們對PACKET_IN,FLOW_REMOVED以及FLOW_MOD這三個消息的具體定義做一個比較:

  • OFPT_PACKET_IN:

v1.0

/* Packet received on port (datapath -> controller). */
struct ofp_packet_in {
struct ofp_header header;
uint32_t buffer_id; /* ID assigned by datapath. */
uint16_t total_len; /* Full length of frame. */
uint16_t in_port; /* Port on which frame was received. */
uint8_t reason; /* Reason packet is being sent (one of OFPR_*) */
uint8_t pad;
uint8_t data[0]; /* Ethernet frame, halfway through 32-bit word,
so the IP header is 32-bit aligned. The
amount of data is inferred from the length
field in the header. Because of padding,
offsetof(struct ofp_packet_in, data) ==
sizeof(struct ofp_packet_in) - 2. */
};
OFP_ASSERT(sizeof(struct ofp_packet_in) == 20);

v1.3

/* Packet received on port (datapath -> controller). */
struct ofp_packet_in {
struct ofp_header header;
uint32_t buffer_id; /* ID assigned by datapath. */
uint16_t total_len; /* Full length of frame. */
uint8_t reason; /* Reason packet is being sent (one of OFPR_*) */
uint8_t table_id; /* ID of the table that was looked up */
uint64_t cookie; /* Cookie of the flow entry that was looked up. */
struct ofp_match match; /* Packet metadata. Variable size. */
/* Followed by:
* - Exactly 2 all-zero padding bytes, then
* - An Ethernet frame whose length is inferred from header.length.
* The padding bytes preceding the Ethernet frame ensure that the IP
* header (if any) following the Ethernet header is 32-bit aligned.
*/
//uint8_t pad[2]; /* Align to 64 bit + 16 bit */
//uint8_t data[0]; /* Ethernet frame */
};
OFP_ASSERT(sizeof(struct ofp_packet_in) == 32);
  • OFPT_FLOW_REMOVED:

v1.0

/* Flow removed (datapath -> controller). */
struct ofp_flow_removed {
struct ofp_header header;
struct ofp_match match; /* Description of fields. */
uint64_t cookie; /* Opaque controller-issued identifier. */
uint16_t priority; /* Priority level of flow entry. */
uint8_t reason; /* One of OFPRR_*. */
uint8_t pad[1]; /* Align to 32-bits. */
uint32_t duration_sec; /* Time flow was alive in seconds. */
uint32_t duration_nsec; /* Time flow was alive in nanoseconds beyond
duration_sec. */
uint16_t idle_timeout; /* Idle timeout from original flow mod. */
uint8_t pad2[2]; /* Align to 64-bits. */
uint64_t packet_count;
uint64_t byte_count;
};
OFP_ASSERT(sizeof(struct ofp_flow_removed) == 88);

v1.3

/* Flow removed (datapath -> controller). */
struct ofp_flow_removed {
struct ofp_header header;
uint64_t cookie; /* Opaque controller-issued identifier. */
uint16_t priority; /* Priority level of flow entry. */
uint8_t reason; /* One of OFPRR_*. */
uint8_t table_id; /* ID of the table */
uint32_t duration_sec; /* Time flow was alive in seconds. */
uint32_t duration_nsec; /* Time flow was alive in nanoseconds beyond
duration_sec. */
uint16_t idle_timeout; /* Idle timeout from original flow mod. */
uint16_t hard_timeout; /* Hard timeout from original flow mod. */
uint64_t packet_count;
uint64_t byte_count;
struct ofp_match match; /* Description of fields. Variable size. */
};
OFP_ASSERT(sizeof(struct ofp_flow_removed) == 56);
  • OFPT_FLOW_MOD

v1.0

/* Flow setup and teardown (controller -> datapath). */
struct ofp_flow_mod {
struct ofp_header header;
struct ofp_match match; /* Fields to match */
uint64_t cookie; /* Opaque controller-issued identifier. */
/* Flow actions. */
uint16_t command; /* One of OFPFC_*. */
uint16_t idle_timeout; /* Idle time before discarding (seconds). */
uint16_t hard_timeout; /* Max time before discarding (seconds). */
uint16_t priority; /* Priority level of flow entry. */
uint32_t buffer_id; /* Buffered packet to apply to (or -1).
Not meaningful for OFPFC_DELETE*. */
uint16_t out_port; /* For OFPFC_DELETE* commands, require
matching entries to include this as an
output port. A value of OFPP_NONE
indicates no restriction. */
uint16_t flags; /* One of OFPFF_*. */
struct ofp_action_header actions[0]; /* The action length is inferred
from the length field in the
header. */
};
OFP_ASSERT(sizeof(struct ofp_flow_mod) == 72);

v1.3

/* Flow setup and teardown (controller -> datapath). */
struct ofp_flow_mod {
struct ofp_header header;
uint64_t cookie; /* Opaque controller-issued identifier. */
uint64_t cookie_mask; /* Mask used to restrict the cookie bits
that must match when the command is
OFPFC_MODIFY* or OFPFC_DELETE*. A value
of 0 indicates no restriction. */
/* Flow actions. */
uint8_t table_id; /* ID of the table to put the flow in.
For OFPFC_DELETE_* commands, OFPTT_ALL
can also be used to delete matching
flows from all tables. */
uint8_t command; /* One of OFPFC_*. */
uint16_t idle_timeout; /* Idle time before discarding (seconds). */
uint16_t hard_timeout; /* Max time before discarding (seconds). */
uint16_t priority; /* Priority level of flow entry. */
uint32_t buffer_id; /* Buffered packet to apply to, or
OFP_NO_BUFFER.
Not meaningful for OFPFC_DELETE*. */
uint32_t out_port; /* For OFPFC_DELETE* commands, require
matching entries to include this as an
output port. A value of OFPP_ANY
indicates no restriction. */
uint32_t out_group; /* For OFPFC_DELETE* commands, require
matching entries to include this as an
output group. A value of OFPG_ANY
indicates no restriction. */
uint16_t flags; /* One of OFPFF_*. */
uint8_t pad[2];
struct ofp_match match; /* Fields to match. Variable size. */
//struct ofp_instruction instructions[0]; /* Instruction set */
};
OFP_ASSERT(sizeof(struct ofp_flow_mod) == 56);
發佈了15 篇原創文章 · 獲贊 12 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章