ovs中的ofproto模块是用于接收并处理openflows消息。这个消息主要包括两种:primary和service。
primary是与openflow controller连接,用于维持连接并发送Asynchronous消息,比如packet-in。这类消息通常包括一些主动连接,比如tcp,ssl,unix。主要是一些指导流转发的流变更消息
service是用于处理ovs-ofctl消息,这类消息由对端负责连接,不主动发送Asynchronous消息。通常包括一些被动连接,比如ptcp,pssl,punix。主要是一些用于测试,监控,查看的消息,比如添加自定义流表,查看ovs流表信息等。
vswitchd在启动后,处理下发消息流程如下:
1. vswitchd.c。该部分作为守护进程,在后台不断运行。作为主模块,主要处理内存监控,处理来自ofproto,ovsdb-server,ovs-appctl等命令。其调用bridge_run()
。
2. bridge_run()
。主要负责对包进行完整处理过程,包括完成必要的配置更新。其作为包裹函数调用bridge_run__()
3. bridge_run__()
。主要包括两部分,一部分调用ofproto_type_run(type)
,让每个datapath type
执行自身的工作。另一部分为ofproto_run(br->ofproto)
处理upcalls
, netflow
, sflow_run
, connmgr_run
等诸多部分。
4. connmgr_run
。主要处理两方面消息:(1).与controller连接,对下发的消息调用handle_openflow
。(2).遍历检测是否有下发的ofctl消息。
5. hanle_openflow
作为包裹函数调用handle_openflow__
,对每个消息进行调用,其中消息以链表形式存在。其代码如下:
static enum ofperr
handle_openflow__(struct ofconn *ofconn, const struct ofpbuf *msg)
OVS_EXCLUDED(ofproto_mutex)
{
const struct ofp_header *oh = ofpbuf_data(msg);
enum ofptype type;
enum ofperr error;
error = ofptype_decode(&type, oh);
if (error) {
return error;
}
if (oh->version >= OFP13_VERSION && ofpmsg_is_stat_request(oh)
&& ofpmp_more(oh)) {
/* We have no buffer implementation for multipart requests.
* Report overflow for requests which consists of multiple
* messages. */
return OFPERR_OFPBRC_MULTIPART_BUFFER_OVERFLOW;
}
switch (type) {
/* OpenFlow requests. */
case OFPTYPE_ECHO_REQUEST:
return handle_echo_request(ofconn, oh);
case OFPTYPE_FEATURES_REQUEST:
return handle_features_request(ofconn, oh);
case OFPTYPE_GET_CONFIG_REQUEST:
return handle_get_config_request(ofconn, oh);
case OFPTYPE_SET_CONFIG:
return handle_set_config(ofconn, oh);
case OFPTYPE_PACKET_OUT:
return handle_packet_out(ofconn, oh);
case OFPTYPE_PORT_MOD:
return handle_port_mod(ofconn, oh);
case OFPTYPE_FLOW_MOD:
return handle_flow_mod(ofconn, oh);
case OFPTYPE_GROUP_MOD:
return handle_group_mod(ofconn, oh);
case OFPTYPE_TABLE_MOD:
return handle_table_mod(ofconn, oh);
case OFPTYPE_METER_MOD:
return handle_meter_mod(ofconn, oh);
case OFPTYPE_BARRIER_REQUEST:
return handle_barrier_request(ofconn, oh);
case OFPTYPE_ROLE_REQUEST:
return handle_role_request(ofconn, oh);
/* OpenFlow replies. */
case OFPTYPE_ECHO_REPLY:
return 0;
/* Nicira extension requests. */
case OFPTYPE_FLOW_MOD_TABLE_ID:
return handle_nxt_flow_mod_table_id(ofconn, oh);
case OFPTYPE_SET_FLOW_FORMAT:
return handle_nxt_set_flow_format(ofconn, oh);
case OFPTYPE_SET_PACKET_IN_FORMAT:
return handle_nxt_set_packet_in_format(ofconn, oh);
case OFPTYPE_SET_CONTROLLER_ID:
return handle_nxt_set_controller_id(ofconn, oh);
case OFPTYPE_FLOW_AGE:
/* Nothing to do. */
return 0;
case OFPTYPE_FLOW_MONITOR_CANCEL:
return handle_flow_monitor_cancel(ofconn, oh);
case OFPTYPE_SET_ASYNC_CONFIG:
return handle_nxt_set_async_config(ofconn, oh);
case OFPTYPE_GET_ASYNC_REQUEST:
return handle_nxt_get_async_request(ofconn, oh);
/* Statistics requests. */
case OFPTYPE_DESC_STATS_REQUEST:
return handle_desc_stats_request(ofconn, oh);
case OFPTYPE_FLOW_STATS_REQUEST:
return handle_flow_stats_request(ofconn, oh);
case OFPTYPE_AGGREGATE_STATS_REQUEST:
return handle_aggregate_stats_request(ofconn, oh);
case OFPTYPE_TABLE_STATS_REQUEST:
return handle_table_stats_request(ofconn, oh);
case OFPTYPE_TABLE_FEATURES_STATS_REQUEST:
return handle_table_features_request(ofconn, oh);
case OFPTYPE_PORT_STATS_REQUEST:
return handle_port_stats_request(ofconn, oh);
case OFPTYPE_QUEUE_STATS_REQUEST:
return handle_queue_stats_request(ofconn, oh);
case OFPTYPE_PORT_DESC_STATS_REQUEST:
return handle_port_desc_stats_request(ofconn, oh);
case OFPTYPE_FLOW_MONITOR_STATS_REQUEST:
return handle_flow_monitor_request(ofconn, oh);
case OFPTYPE_METER_STATS_REQUEST:
case OFPTYPE_METER_CONFIG_STATS_REQUEST:
return handle_meter_request(ofconn, oh, type);
case OFPTYPE_METER_FEATURES_STATS_REQUEST:
return handle_meter_features_request(ofconn, oh);
case OFPTYPE_GROUP_STATS_REQUEST:
return handle_group_stats_request(ofconn, oh);
case OFPTYPE_GROUP_DESC_STATS_REQUEST:
return handle_group_desc_stats_request(ofconn, oh);
case OFPTYPE_GROUP_FEATURES_STATS_REQUEST:
return handle_group_features_stats_request(ofconn, oh);
case OFPTYPE_QUEUE_GET_CONFIG_REQUEST:
return handle_queue_get_config_request(ofconn, oh);
case OFPTYPE_BUNDLE_CONTROL:
return handle_bundle_control(ofconn, oh);
case OFPTYPE_BUNDLE_ADD_MESSAGE:
return handle_bundle_add(ofconn, oh);
case OFPTYPE_HELLO:
case OFPTYPE_ERROR:
case OFPTYPE_FEATURES_REPLY:
case OFPTYPE_GET_CONFIG_REPLY:
case OFPTYPE_PACKET_IN:
case OFPTYPE_FLOW_REMOVED:
case OFPTYPE_PORT_STATUS:
case OFPTYPE_BARRIER_REPLY:
case OFPTYPE_QUEUE_GET_CONFIG_REPLY:
case OFPTYPE_DESC_STATS_REPLY:
case OFPTYPE_FLOW_STATS_REPLY:
case OFPTYPE_QUEUE_STATS_REPLY:
case OFPTYPE_PORT_STATS_REPLY:
case OFPTYPE_TABLE_STATS_REPLY:
case OFPTYPE_AGGREGATE_STATS_REPLY:
case OFPTYPE_PORT_DESC_STATS_REPLY:
case OFPTYPE_ROLE_REPLY:
case OFPTYPE_FLOW_MONITOR_PAUSED:
case OFPTYPE_FLOW_MONITOR_RESUMED:
case OFPTYPE_FLOW_MONITOR_STATS_REPLY:
case OFPTYPE_GET_ASYNC_REPLY:
case OFPTYPE_GROUP_STATS_REPLY:
case OFPTYPE_GROUP_DESC_STATS_REPLY:
case OFPTYPE_GROUP_FEATURES_STATS_REPLY:
case OFPTYPE_METER_STATS_REPLY:
case OFPTYPE_METER_CONFIG_STATS_REPLY:
case OFPTYPE_METER_FEATURES_STATS_REPLY:
case OFPTYPE_TABLE_FEATURES_STATS_REPLY:
case OFPTYPE_ROLE_STATUS:
default:
if (ofpmsg_is_stat_request(oh)) {
return OFPERR_OFPBRC_BAD_STAT;
} else {
return OFPERR_OFPBRC_BAD_TYPE;
}
}
}
参考
http://blog.csdn.net/vonzhoufz/article/details/29190281