(rule->cr.priority <= UINT16_MAX ? UINT16_MAX
: rule->cr.priority));
+ /* Insert 'subrule' into the classifier and compose actions for it. */
old_sr = rule_from_cls_rule(classifier_insert(&p->cls, &subrule->cr));
if (old_sr) {
if (!old_sr->super) {
- /* Put old_sr back. */
+ /* We just replaced a real rule with a subrule. We shouldn't
+ * have done that. Put old_sr back and destroy the subrule. */
cls_rule_replace(&p->cls, &subrule->cr, &old_sr->cr);
rule_destroy(subrule);
-
- /* Execute old_sr on packet. */
- rule_install(p, old_sr, NULL);
- if (!dpif_execute(&p->dpif, msg->port,
- old_sr->odp_actions, old_sr->n_odp_actions,
- &payload)) {
- old_sr->packet_count++;
- old_sr->byte_count += payload.size;
- }
- ofpbuf_delete(packet);
- return;
+ subrule = old_sr;
} else {
+ /* XXX this seems wrong: why are we accounting the old rule's
+ * traffic to the new one? */
subrule->packet_count += old_sr->packet_count;
subrule->byte_count += old_sr->byte_count;
rule_destroy(old_sr);
+ rule_make_actions(p, subrule, packet);
}
+ } else {
+ rule_make_actions(p, subrule, packet);
}
/* Install flow entry into datapath. */
- rule_make_actions(p, subrule, packet);
rule_install(p, subrule, NULL);
} else {
subrule = rule;