datapath: Convert kernel priority actions into match/set.
[sliver-openvswitch.git] / lib / dpif.c
index c6940b1..cc6e805 100644 (file)
@@ -388,33 +388,6 @@ dpif_get_dp_stats(const struct dpif *dpif, struct dpif_dp_stats *stats)
     return error;
 }
 
-/* Retrieves the current IP fragment handling policy for 'dpif' into
- * '*drop_frags': true indicates that fragments are dropped, false indicates
- * that fragments are treated in the same way as other IP packets (except that
- * the L4 header cannot be read).  Returns 0 if successful, otherwise a
- * positive errno value. */
-int
-dpif_get_drop_frags(const struct dpif *dpif, bool *drop_frags)
-{
-    int error = dpif->dpif_class->get_drop_frags(dpif, drop_frags);
-    if (error) {
-        *drop_frags = false;
-    }
-    log_operation(dpif, "get_drop_frags", error);
-    return error;
-}
-
-/* Changes 'dpif''s treatment of IP fragments to 'drop_frags', whose meaning is
- * the same as for the get_drop_frags member function.  Returns 0 if
- * successful, otherwise a positive errno value. */
-int
-dpif_set_drop_frags(struct dpif *dpif, bool drop_frags)
-{
-    int error = dpif->dpif_class->set_drop_frags(dpif, drop_frags);
-    log_operation(dpif, "set_drop_frags", error);
-    return error;
-}
-
 /* Attempts to add 'netdev' as a port on 'dpif'.  If successful, returns 0 and
  * sets '*port_nop' to the new port's port number (if 'port_nop' is non-null).
  * On failure, returns a positive errno value and sets '*port_nop' to
@@ -542,6 +515,23 @@ dpif_get_max_ports(const struct dpif *dpif)
     return dpif->dpif_class->get_max_ports(dpif);
 }
 
+/* Returns the Netlink PID value to supply in OVS_ACTION_ATTR_USERSPACE actions
+ * as the OVS_USERSPACE_ATTR_PID attribute's value, for use in flows whose
+ * packets arrived on port 'port_no'.
+ *
+ * The return value is only meaningful when DPIF_UC_ACTION has been enabled in
+ * the 'dpif''s listen mask.  It is allowed to change when DPIF_UC_ACTION is
+ * disabled and then re-enabled, so a client that does that must be prepared to
+ * update all of the flows that it installed that contain
+ * OVS_ACTION_ATTR_USERSPACE actions. */
+uint32_t
+dpif_port_get_pid(const struct dpif *dpif, uint16_t port_no)
+{
+    return (dpif->dpif_class->port_get_pid
+            ? (dpif->dpif_class->port_get_pid)(dpif, port_no)
+            : 0);
+}
+
 /* Looks up port number 'port_no' in 'dpif'.  On success, returns 0 and copies
  * the port's name into the 'name_size' bytes in 'name', ensuring that the
  * result is null-terminated.  On failure, returns a positive errno value and
@@ -971,6 +961,51 @@ dpif_execute(struct dpif *dpif,
     return error;
 }
 
+/* Executes each of the 'n_ops' operations in 'ops' on 'dpif', in the order in
+ * which they are specified, placing each operation's results in the "output"
+ * members documented in comments.
+ *
+ * This function exists because some datapaths can perform batched operations
+ * faster than individual operations. */
+void
+dpif_operate(struct dpif *dpif, union dpif_op **ops, size_t n_ops)
+{
+    size_t i;
+
+    if (dpif->dpif_class->operate) {
+        dpif->dpif_class->operate(dpif, ops, n_ops);
+        return;
+    }
+
+    for (i = 0; i < n_ops; i++) {
+        union dpif_op *op = ops[i];
+        struct dpif_flow_put *put;
+        struct dpif_execute *execute;
+
+        switch (op->type) {
+        case DPIF_OP_FLOW_PUT:
+            put = &op->flow_put;
+            put->error = dpif_flow_put(dpif, put->flags,
+                                       put->key, put->key_len,
+                                       put->actions, put->actions_len,
+                                       put->stats);
+            break;
+
+        case DPIF_OP_EXECUTE:
+            execute = &op->execute;
+            execute->error = dpif_execute(dpif, execute->key, execute->key_len,
+                                          execute->actions,
+                                          execute->actions_len,
+                                          execute->packet);
+            break;
+
+        default:
+            NOT_REACHED();
+        }
+    }
+}
+
+
 /* Returns a string that represents 'type', for use in log messages. */
 const char *
 dpif_upcall_type_to_string(enum dpif_upcall_type type)
@@ -1008,7 +1043,12 @@ dpif_recv_get_mask(const struct dpif *dpif, int *listen_mask)
 /* Sets 'dpif''s "listen mask" to 'listen_mask'.  A 1-bit of value 2**X set in
  * '*listen_mask' requests that dpif_recv() will receive messages of the type
  * (from "enum dpif_upcall_type") with value X.  Returns 0 if successful,
- * otherwise a positive errno value. */
+ * otherwise a positive errno value.
+ *
+ * Turning DPIF_UC_ACTION off and then back on may change the Netlink PID
+ * assignments returned by dpif_port_get_pid().  If the client does this, it
+ * must update all of the flows that have OVS_ACTION_ATTR_USERSPACE actions
+ * using the new PID assignment. */
 int
 dpif_recv_set_mask(struct dpif *dpif, int listen_mask)
 {
@@ -1089,9 +1129,9 @@ dpif_get_netflow_ids(const struct dpif *dpif,
 }
 
 /* Translates OpenFlow queue ID 'queue_id' (in host byte order) into a priority
- * value for use in the OVS_ACTION_ATTR_SET_PRIORITY action.  On success,
- * returns 0 and stores the priority into '*priority'.  On failure, returns a
- * positive errno value and stores 0 into '*priority'. */
+ * value used for setting packet priority.
+ * On success, returns 0 and stores the priority into '*priority'.
+ * On failure, returns a positive errno value and stores 0 into '*priority'. */
 int
 dpif_queue_to_priority(const struct dpif *dpif, uint32_t queue_id,
                        uint32_t *priority)