ofproto_flow_mod(&ofproto->up, fm);
}
+/* Resets the modified time for 'rule' or an equivalent rule. If 'rule' is not
+ * in the classifier, but an equivalent rule is, unref 'rule' and ref the new
+ * rule. Otherwise if 'rule' is no longer installed in the classifier,
+ * reinstall it.
+ *
+ * Returns the rule whose modified time has been reset. */
+struct rule_dpif *
+ofproto_dpif_refresh_rule(struct rule_dpif *rule)
+{
+ return rule_dpif_cast(ofproto_refresh_rule(&rule->up));
+}
+
/* Appends 'pin' to the queue of "packet ins" to be sent to the controller.
* Takes ownership of 'pin' and pin->packet. */
void
odp_flow_key_from_flow(&key, &flow, 0);
error = dpif_flow_put(backer->dpif, DPIF_FP_CREATE | DPIF_FP_MODIFY,
- key.data, key.size, NULL, 0, NULL, 0, NULL);
+ ofpbuf_data(&key), ofpbuf_size(&key), NULL, 0, NULL,
+ 0, NULL);
if (error && error != EEXIST) {
if (error != EINVAL) {
VLOG_WARN("%s: Reciculation flow probe failed (%s)",
goto done;
}
- error = dpif_flow_del(backer->dpif, key.data, key.size, NULL);
+ error = dpif_flow_del(backer->dpif, ofpbuf_data(&key), ofpbuf_size(&key),
+ NULL);
if (error) {
VLOG_WARN("%s: failed to delete recirculation feature probe flow",
dpif_name(backer->dpif));
* the lookup. Returns the table_id where a match or miss occurred.
*
* The return value will be zero unless there was a miss and
- * O!-TC_TABLE_MISS_CONTINUE is in effect for the sequence of tables
+ * OFPTC11_TABLE_MISS_CONTINUE is in effect for the sequence of tables
* where misses occur. */
uint8_t
rule_dpif_lookup(struct ofproto_dpif *ofproto, struct flow *flow,
* - RULE_OFPTC_TABLE_MISS_CONTROLLER if no rule was found and either:
* + 'honor_table_miss' is false
* + a table miss configuration specified that the packet should be
+ * sent to the controller in this case.
*
* - RULE_DPIF_LOOKUP_VERDICT_DROP if no rule was found, 'honor_table_miss'
* is true and a table miss configuration specified that the packet
struct trace_ctx {
struct xlate_out xout;
struct xlate_in xin;
+ const struct flow *key;
struct flow flow;
struct flow_wildcards wc;
struct ds *result;
{
ds_put_char_multiple(result, '\t', level);
ds_put_format(result, "%s: ", title);
- if (flow_equal(&trace->xin.flow, &trace->flow)) {
+ /* Do not report unchanged flows for resubmits. */
+ if ((level > 0 && flow_equal(&trace->xin.flow, &trace->flow))
+ || (level == 0 && flow_equal(&trace->xin.flow, trace->key))) {
ds_put_cstr(result, "unchanged");
} else {
flow_format(result, &trace->xin.flow);
ds_put_char_multiple(result, '\t', level);
ds_put_format(result, "%s: ", title);
flow_wildcards_or(&trace->wc, &trace->xout.wc, &trace->wc);
- match_init(&match, &trace->flow, &trace->wc);
+ match_init(&match, trace->key, &trace->wc);
match_format(&match, result, OFP_DEFAULT_PRIORITY);
ds_put_char(result, '\n');
}
if (rule || ofpacts) {
trace.result = ds;
- trace.flow = *flow;
+ trace.key = flow; /* Original flow key, used for megaflow. */
+ trace.flow = *flow; /* May be modified by actions. */
xlate_in_init(&trace.xin, ofproto, flow, rule, ntohs(flow->tcp_flags),
packet);
if (ofpacts) {
fm.buffer_id = 0;
fm.out_port = 0;
fm.flags = OFPUTIL_FF_HIDDEN_FIELDS | OFPUTIL_FF_NO_READONLY;
- fm.ofpacts = ofpacts->data;
- fm.ofpacts_len = ofpacts->size;
+ fm.ofpacts = ofpbuf_data(ofpacts);
+ fm.ofpacts_len = ofpbuf_size(ofpacts);
error = ofproto_flow_mod(&ofproto->up, &fm);
if (error) {