ofproto: New function ofproto_refresh_rule().
[sliver-openvswitch.git] / ofproto / ofproto-dpif.c
index cb01516..52e47c2 100644 (file)
@@ -362,6 +362,18 @@ ofproto_dpif_flow_mod(struct ofproto_dpif *ofproto,
     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
@@ -954,7 +966,8 @@ check_recirc(struct dpif_backer *backer)
     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)",
@@ -963,7 +976,8 @@ check_recirc(struct dpif_backer *backer)
         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));
@@ -3216,7 +3230,7 @@ rule_dpif_lookup__ (struct ofproto_dpif *ofproto, const struct flow *flow,
  * 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,
@@ -3291,6 +3305,7 @@ rule_dpif_lookup_in_table(struct ofproto_dpif *ofproto, uint8_t table_id,
  *    - 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
@@ -3778,6 +3793,7 @@ ofproto_unixctl_fdb_show(struct unixctl_conn *conn, int argc OVS_UNUSED,
 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;
@@ -3818,7 +3834,9 @@ trace_format_flow(struct ds *result, int level, const char *title,
 {
     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);
@@ -3863,7 +3881,7 @@ trace_format_megaflow(struct ds *result, int level, const char *title,
     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');
 }
@@ -4185,7 +4203,8 @@ ofproto_trace(struct ofproto_dpif *ofproto, struct flow *flow,
 
     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) {
@@ -4778,8 +4797,8 @@ ofproto_dpif_add_internal_flow(struct ofproto_dpif *ofproto,
     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) {