ofproto-dpif: Batch flow uninstallations due to expiration.
[sliver-openvswitch.git] / lib / dpif.c
index 73696e4..35df1e5 100644 (file)
@@ -89,6 +89,8 @@ static void log_operation(const struct dpif *, const char *operation,
 static bool should_log_flow_message(int error);
 static void log_flow_put_message(struct dpif *, const struct dpif_flow_put *,
                                  int error);
+static void log_flow_del_message(struct dpif *, const struct dpif_flow_del *,
+                                 int error);
 static void log_execute_message(struct dpif *, const struct dpif_execute *,
                                 int error);
 
@@ -815,6 +817,21 @@ dpif_flow_put(struct dpif *dpif, enum dpif_flow_put_flags flags,
     return dpif_flow_put__(dpif, &put);
 }
 
+static int
+dpif_flow_del__(struct dpif *dpif, struct dpif_flow_del *del)
+{
+    int error;
+
+    COVERAGE_INC(dpif_flow_del);
+
+    error = dpif->dpif_class->flow_del(dpif, del);
+    if (error && del->stats) {
+        memset(del->stats, 0, sizeof *del->stats);
+    }
+    log_flow_del_message(dpif, del, error);
+    return error;
+}
+
 /* Deletes a flow from 'dpif' and returns 0, or returns ENOENT if 'dpif' does
  * not contain such a flow.  The flow is specified by the Netlink attributes
  * with types OVS_KEY_ATTR_* in the 'key_len' bytes starting at 'key'.
@@ -826,19 +843,12 @@ dpif_flow_del(struct dpif *dpif,
               const struct nlattr *key, size_t key_len,
               struct dpif_flow_stats *stats)
 {
-    int error;
+    struct dpif_flow_del del;
 
-    COVERAGE_INC(dpif_flow_del);
-
-    error = dpif->dpif_class->flow_del(dpif, key, key_len, stats);
-    if (error && stats) {
-        memset(stats, 0, sizeof *stats);
-    }
-    if (should_log_flow_message(error)) {
-        log_flow_message(dpif, error, "flow_del", key, key_len,
-                         !error ? stats : NULL, NULL, 0);
-    }
-    return error;
+    del.key = key;
+    del.key_len = key_len;
+    del.stats = stats;
+    return dpif_flow_del__(dpif, &del);
 }
 
 /* Initializes 'dump' to begin dumping the flows in a dpif.
@@ -994,6 +1004,10 @@ dpif_operate(struct dpif *dpif, struct dpif_op **ops, size_t n_ops)
                 log_flow_put_message(dpif, &op->u.flow_put, op->error);
                 break;
 
+            case DPIF_OP_FLOW_DEL:
+                log_flow_del_message(dpif, &op->u.flow_del, op->error);
+                break;
+
             case DPIF_OP_EXECUTE:
                 log_execute_message(dpif, &op->u.execute, op->error);
                 break;
@@ -1010,6 +1024,10 @@ dpif_operate(struct dpif *dpif, struct dpif_op **ops, size_t n_ops)
             op->error = dpif_flow_put__(dpif, &op->u.flow_put);
             break;
 
+        case DPIF_OP_FLOW_DEL:
+            op->error = dpif_flow_del__(dpif, &op->u.flow_del);
+            break;
+
         case DPIF_OP_EXECUTE:
             op->error = dpif_execute__(dpif, &op->u.execute);
             break;
@@ -1245,6 +1263,16 @@ log_flow_put_message(struct dpif *dpif, const struct dpif_flow_put *put,
     }
 }
 
+static void
+log_flow_del_message(struct dpif *dpif, const struct dpif_flow_del *del,
+                     int error)
+{
+    if (should_log_flow_message(error)) {
+        log_flow_message(dpif, error, "flow_del", del->key, del->key_len,
+                         !error ? del->stats : NULL, NULL, 0);
+    }
+}
+
 static void
 log_execute_message(struct dpif *dpif, const struct dpif_execute *execute,
                     int error)