上两篇分析了controller连接建立的完整流程,本篇分析下接收openflow报文的过程,openflow报文的处理在后续文章中分析。 整个调用过程,可以根据上一篇的对象关系图得出,本篇只是把调用关系细化到函数。
1、connmgr_run函数
if (mgr->in_band) {
if (!in_band_run(mgr->in_band)) {
in_band_destroy(mgr->in_band);
mgr->in_band = NULL;
}
}
LIST_FOR_EACH_SAFE (ofconn, next_ofconn, node, &mgr->all_conns) {
ofconn_run(ofconn, handle_openflow); //all_conns有两部分组成:controller连接和ofservice
}
ofmonitor_run(mgr);
/* Fail-open maintenance. Do this after processing the ofconns since
* fail-open checks the status of the controller rconn. */
if (mgr->fail_open) {
fail_open_run(mgr->fail_open);
}
2、ofconn_run函数
static void
ofconn_run(struct ofconn *ofconn,
void (*handle_openflow)(struct ofconn *,
const struct ofpbuf *ofp_msg))
{
struct connmgr *mgr = ofconn->connmgr;
size_t i;
for (i = 0; i < N_SCHEDULERS; i++) {
struct ovs_list txq;
pinsched_run(ofconn->schedulers[i], &txq);
do_send_packet_ins(ofconn, &txq);
}
rconn_run(ofconn->rconn); //该调用链为 vconn_run->stream_run, 对于tcp的连接,主要行为是判断是否有发送报文,有则发送之
/* Limit the number of iterations to avoid starving other tasks. */
for (i = 0; i < 50 && ofconn_may_recv(ofconn); i++) {
struct ofpbuf *of_msg = rconn_recv(ofconn->rconn); //接收报文
if (!of_msg) {
break;
}
if (mgr->fail_open) {
fail_open_maybe_recover(mgr->fail_open);
}
handle_openflow(o