[ovs-discuss] Question about handle_odp_miss_msg() in ofproto.c

YIMIN CHEN ymchen.nbzj at gmail.com
Tue Jun 5 02:44:58 UTC 2012


Hi,

Sorry to bother you again!

I am working on openvswitch 1.1.0pre2 package, and trying to
understand the logic in handle_odp_miss_msg() in ofproto.c. I would
really appreciate anyone familiar with this code giving me some
feedback. I have copied the code snip below.

My question is:
1) What is the main difference between rule_make_actions() and
rule_execute()? In handle_odp_miss_msg(), we call both
rule_make_actions() and rule_execute(), both calls xact_actions() that
goes through list of actions to contruct odp actions. I can see
rule_execute() not only calls xact_actions() to construct, but also
execute odp actions. But I couldn't figure out the reason for doing
construction twice. I must be missing some logic here. Could anyone
please clarify for me? Same questions I inlined below as well.

Thanks!

static void
handle_odp_miss_msg(struct ofproto *p, struct ofpbuf *packet)
{
    struct odp_msg *msg = packet->data;
    struct rule *rule;
    struct ofpbuf payload;
    flow_t flow;
...
...
    rule = lookup_valid_rule(p, &flow);
    if (!rule) {
        /* Don't send a packet-in if OFPPC_NO_PACKET_IN asserted. */
        struct ofport *port = port_array_get(&p->ports, msg->port);
        if (port) {
            if (port->opp.config & OFPPC_NO_PACKET_IN) {
                COVERAGE_INC(ofproto_no_packet_in);
                /* XXX install 'drop' flow entry */
                ofpbuf_delete(packet);
                return;
            }
        } else {
            VLOG_WARN_RL(&rl, "packet-in on unknown port %"PRIu16, msg->port);
        }

        COVERAGE_INC(ofproto_packet_in);
        send_packet_in(p, packet);
        return;
    }

    if (rule->cr.wc.wildcards) { <=== so if it is a wildcard rule we
construct the odp actions
        rule = rule_create_subrule(p, rule, &flow);
        rule_make_actions(p, rule, packet);
    } else {
        if (!rule->may_install) {
            /* The rule is not installable, that is, we need to process every
             * packet, so process the current packet and set its actions into
             * 'subrule'. */
            rule_make_actions(p, rule, packet);
        } else {
            /* XXX revalidate rule if it needs it */
        }
    }

    if (rule->super && rule->super->cr.priority == FAIL_OPEN_PRIORITY) {
        /*
         * Extra-special case for fail-open mode.
         *
         * We are in fail-open mode and the packet matched the fail-open rule,
         * but we are connected to a controller too.  We should send the packet
         * up to the controller in the hope that it will try to set up a flow
         * and thereby allow us to exit fail-open.
         *
         * See the top-level comment in fail-open.c for more information.
         */
        send_packet_in(p, ofpbuf_clone_with_headroom(packet,
                                                     DPIF_RECV_MSG_PADDING));
    }

    ofpbuf_pull(packet, sizeof *msg);
    rule_execute(p, rule, packet, &flow); <== in rule_execute
    rule_reinstall(p, rule);

static void
rule_execute(struct ofproto *ofproto, struct rule *rule,
             struct ofpbuf *packet, const flow_t *flow)
{
    const union odp_action *actions;
    struct odp_flow_stats stats;
    size_t n_actions;
    struct odp_actions a;

    assert(ofpbuf_headroom(packet) >= sizeof(struct ofp_packet_in));

    /* Grab or compose the ODP actions.
     *
     * The special case for an exact-match 'rule' where 'flow' is not the
     * rule's flow is important to avoid, e.g., sending a packet out its input
     * port simply because the ODP actions were composed for the wrong
     * scenario. */
    if (rule->cr.wc.wildcards || !flow_equal(flow, &rule->cr.flow)) {
<=== if wildcard we call xlate_actions() again, why?
        struct rule *super = rule->super ? rule->super : rule;
        if (xlate_actions(super->actions, super->n_actions, flow, ofproto,
                          packet, &a, NULL, 0, NULL)) {
            ofpbuf_delete(packet);
            return;
        }
        actions = a.actions;
        n_actions = a.n_actions;
    } else {
        actions = rule->odp_actions;
        n_actions = rule->n_odp_actions;
    }



More information about the discuss mailing list