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; } _______________________________________________ discuss mailing list discuss@openvswitch.org http://openvswitch.org/mailman/listinfo/discuss