一、搭建下图所示拓扑,完成相关 IP 配置,并实现主机与主机之间的 IP 通信。用抓包软件获取控制器与交换机之间的通信数据。
(1)拓扑
(2)主机互ping
(3)抓包结果
(4)建立连接的交互图与文字说明
当双方hello报文中openflow版本可以互相兼容,则会按照上图所示的流程继续建立连接;若版本不兼容,则发送error消息后断开链接
(5)交换机与控制器建立通信时是使用TCP协议还是UDP协议?
TCP协议
二、进阶实验
(1)header(所有的openflow消息必有的部分)
struct ofp_header {
uint8_t version; /* openflow协议版本 */
uint8_t type; /*openflow消息类型 */
uint16_t length; /* 包括头部的openflow报文长度*/
uint32_t xid; /* 与此数据包关联的事务id(答复时使用与请求时相同的id)*/
};
(2)hello
struct ofp_hello {
struct ofp_header header;
};
(3)port_status
struct ofp_port_status {
struct ofp_header header;
uint8_t reason; /* One of OFPPR_*. */
uint8_t pad[7]; /* Align to 64-bits. */
struct ofp_phy_port desc;
};
OFP_ASSERT(sizeof(struct ofp_port_status) == 64);
(4)features_request
struct ofp_features_request{
struct ofp_header header;
};
(5)set config
struct ofp_switch_config {
struct ofp_header header;
uint16_t flags; /* OFPC_* flags. */
uint16_t miss_send_len; /* Max bytes of new flow that datapath should
send to the controller. */
};
OFP_ASSERT(sizeof(struct ofp_switch_config) == 12);
enum ofp_config_flags {
/* Handling of IP fragments. */
OFPC_FRAG_NORMAL = 0, /* No special handling for fragments. */
OFPC_FRAG_DROP = 1, /* Drop fragments. */
OFPC_FRAG_REASM = 2, /* Reassemble (only if OFPC_IP_REASM set). */
OFPC_FRAG_MASK = 3
};
(6)features_reply
struct ofp_queue_get_config_reply {
struct ofp_header header;
uint16_t port;
uint8_t pad[6];
struct ofp_packet_queue queues[0]; /* List of configured queues. */
};
OFP_ASSERT(sizeof(struct ofp_queue_get_config_reply) == 16);
struct ofp_aggregate_stats_reply {
uint64_t packet_count; /* Number of packets in flows. */
uint64_t byte_count; /* Number of bytes in flows. */
uint32_t flow_count; /* Number of flows. */
uint8_t pad[4]; /* Align to 64 bits. */
};
OFP_ASSERT(sizeof(struct ofp_aggregate_stats_reply) == 24);
struct ofp_stats_reply {
struct ofp_header header;
uint16_t type; /* One of the OFPST_* constants. */
uint16_t flags; /* OFPSF_REPLY_* flags. */
uint8_t body[0]; /* Body of the reply. */
};
OFP_ASSERT(sizeof(struct ofp_stats_reply) == 12);
(7)packet_in
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);
(8)packet_out
struct ofp_packet_out {
struct ofp_header header;
uint32_t buffer_id; /* ID assigned by datapath (-1 if none). */
uint16_t in_port; /* Packet's input port (OFPP_NONE if none). */
uint16_t actions_len; /* Size of action array in bytes. */
struct ofp_action_header actions[0]; /* Actions. */
/* uint8_t data[0]; */ /* Packet data. The length is inferred
from the length field in the header.
(Only meaningful if buffer_id == -1.) */
};
OFP_ASSERT(sizeof(struct ofp_packet_out) == 16);
三、实验总结
本次实验难度适中,用wireshark抓包时选择“any”,在过滤中写入openflow_v1来筛出所有openflow包。要在拓扑建立前抓包。通过观察openflow包,总结出交换机与控制器建立连接的步骤,以及通过观察源端口号和目的端口号,总结出报文的具体发送过程。而在拓展实验中,经查阅资料,发现openflow源码存放在openflow/include/openflow/openflow.h处,通过gedit命令查看后,与openflow包的信息进行比对,最终了解了OpenFlow主要消息类型对应的数据结构定义。控制器与交换机连接建立完成后,控制器下发转发信息,交换机上传网络资源信息,最终实现全网主机的互通。
标签:struct,OpenFlow,openflow,实践,packet,uint8,header,ofp,实验 From: https://www.cnblogs.com/garty/p/16748650.html