整理处理流程图:
1. 通过对of msg进行解码,可以得到具体的flow_mod以及对应的actions,(这里看增加流表的情况),接下来add_flow函数就会根据flow_mod制定的流来构建特定的规则分类器,增加到oftable中。具体过程是:选择一个合适的表;构建一个分类规则(关键代码如下);插入。这样此次通信的任务就完成了,当再有packet因为在datapath层匹配失败上传到用户空间时,就会找到oftable中的分类规则,从而执行其中的动作。
cls_rule_init(&rule->cr, &fm->match, fm->priority);
rule->ofproto = ofproto;
rule->created = rule->modified = rule->used = time_msec();
rule->idle_timeout = fm->idle_timeout;
rule->hard_timeout = fm->hard_timeout;
rule->table_id = table - ofproto->tables;
rule->send_flow_removed = (fm->flags & OFPFF_SEND_FLOW_REM) != 0;
rule->ofpacts = xmemdup(fm->ofpacts, fm->ofpacts_len);
rule->ofpacts_len = fm->ofpacts_len;
rule->evictable = true;
/* Insert new rule. */
victim = oftable_replace_rule(rule);
2. 解码的过程是根据消息头中长度信息,以及action长度,类型字段得到对应的实体。
关键代码为:
if (raw == OFPRAW_OFPT10_FLOW_MOD) {
const struct ofp10_flow_mod *ofm; //1.0协议
enum ofperr error;
ofm = ofpbuf_pull(&b, sizeof *ofm); /* Get the ofp10_flow_mod. */
/* Translate the rule. */
ofputil_match_from_ofp10_match(&ofm->match, &fm->match);
//将刚才解析出来的ofm转换成通用的ofputil_flow_mod;
ofputil_normalize_match(&fm->match);
error = ofpacts_pull_openflow10(&b, b.size, ofpacts); /* Now get the actions. */
/* OpenFlow 1.0 says that exact-match rules have to have the highest possible priority. */
fm->priority = (ofm->match.wildcards & htonl(OFPFW10_ALL)
? ntohs(ofm->priority)
: UINT16_MAX);
/* Translate the message. */
command = ntohs(ofm->command);
fm->cookie = htonll(0);
fm->cookie_mask = htonll(0);
fm->new_cookie = ofm->cookie;
fm->idle_timeout = ntohs(ofm->idle_timeout);
fm->hard_timeout = ntohs(ofm->hard_timeout);
fm->buffer_id = ntohl(ofm->buffer_id);
fm->out_port = ntohs(ofm->out_port);
fm->flags = ntohs(ofm->flags);
3. 上述完成add flow之后,用户空间的分类表得到了更新。此时如果对应的packet到达时,struct rule_dpif *rule = rule_dpif_lookup(ofproto, &miss->flow);
就会找个相应的规则,facet的创建依赖于它。
OVS响应OFPT_FLOW_MOD过程分析