首页 > 代码库 > OVS响应OFPT_FLOW_MOD过程分析

OVS响应OFPT_FLOW_MOD过程分析


整理处理流程图:



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的创建依赖于它。