dpif: Document datapath masking.
[sliver-openvswitch.git] / lib / dpif.h
index 11d7445..499ee79 100644 (file)
  * Flow Table
  * ==========
  *
- * The flow table is a hash table of "flow entries".  Each flow entry contains:
+ * The flow table is a collection of "flow entries".  Each flow entry contains:
  *
  *    - A "flow", that is, a summary of the headers in an Ethernet packet.  The
- *      flow is the hash key and thus must be unique within the flow table.
- *      Flows are fine-grained entities that include L2, L3, and L4 headers.  A
- *      single TCP connection consists of two flows, one in each direction.
+ *      flow must be unique within the flow table.  Flows are fine-grained
+ *      entities that include L2, L3, and L4 headers.  A single TCP connection
+ *      consists of two flows, one in each direction.
  *
  *      In Open vSwitch userspace, "struct flow" is the typical way to describe
  *      a flow, but the datapath interface uses a different data format to
  *      "struct ovs_key_*" in include/linux/openvswitch.h for details.
  *      lib/odp-util.h defines several functions for working with these flows.
  *
- *      (In case you are familiar with OpenFlow, datapath flows are analogous
- *      to OpenFlow flow matches.  The most important difference is that
- *      OpenFlow allows fields to be wildcarded and prioritized, whereas a
- *      datapath's flow table is a hash table so every flow must be
- *      exact-match, thus without priorities.)
+ *    - A "mask" that, for each bit in the flow, specifies whether the datapath
+ *      should consider the corresponding flow bit when deciding whether a
+ *      given packet matches the flow entry.  The original datapath design did
+ *      not support matching: every flow entry was exact match.  With the
+ *      addition of a mask, the interface supports datapaths with a spectrum of
+ *      wildcard matching capabilities, from those that only support exact
+ *      matches to those that support bitwise wildcarding on the entire flow
+ *      key, as well as datapaths with capabilities somewhere in between.
+ *
+ *      Datapaths do not provide a way to query their wildcarding capabilities,
+ *      nor is it expected that the client should attempt to probe for the
+ *      details of their support.  Instead, a client installs flows with masks
+ *      that wildcard as many bits as acceptable.  The datapath then actually
+ *      wildcards as many of those bits as it can and changes the wildcard bits
+ *      that it does not support into exact match bits.  A datapath that can
+ *      wildcard any bit, for example, would install the supplied mask, an
+ *      exact-match only datapath would install an exact-match mask regardless
+ *      of what mask the client supplied, and a datapath in the middle of the
+ *      spectrum would selectively change some wildcard bits into exact match
+ *      bits.
+ *
+ *      Regardless of the requested or installed mask, the datapath retains the
+ *      original flow supplied by the client.  (It does not, for example, "zero
+ *      out" the wildcarded bits.)  This allows the client to unambiguously
+ *      identify the flow entry in later flow table operations.
+ *
+ *      The flow table does not have priorities; that is, all flow entries have
+ *      equal priority.  Detecting overlapping flow entries is expensive in
+ *      general, so the datapath is not required to do it.  It is primarily the
+ *      client's responsibility not to install flow entries whose flow and mask
+ *      combinations overlap.
  *
  *    - A list of "actions" that tell the datapath what to do with packets
  *      within a flow.  Some examples of actions are OVS_ACTION_ATTR_OUTPUT,
  *      location.
  *
  *    - Adding and removing ports to achieve a new configuration.
+ *
+ *
+ * Thread-safety
+ * =============
+ *
+ * Most of the dpif functions are fully thread-safe: they may be called from
+ * any number of threads on the same or different dpif objects.  The exceptions
+ * are:
+ *
+ *    - dpif_port_poll() and dpif_port_poll_wait() are conditionally
+ *      thread-safe: they may be called from different threads only on
+ *      different dpif objects.
+ *
+ *    - Functions that operate on struct dpif_port_dump or struct
+ *      dpif_flow_dump are conditionally thread-safe with respect to those
+ *      objects.  That is, one may dump ports or flows from any number of
+ *      threads at once, but each thread must use its own struct dpif_port_dump
+ *      or dpif_flow_dump.
  */
 #ifndef DPIF_H
 #define DPIF_H 1
@@ -369,6 +413,9 @@ struct dpif_dp_stats {
     uint64_t n_missed;          /* Number of flow table misses. */
     uint64_t n_lost;            /* Number of misses not sent to userspace. */
     uint64_t n_flows;           /* Number of flows present. */
+    uint64_t n_masks;           /* Number of mega flow masks. */
+    uint64_t n_mask_hit;        /* Number of mega flow masks visited for
+                                   flow table matches. */
 };
 int dpif_get_dp_stats(const struct dpif *, struct dpif_dp_stats *);
 
@@ -377,8 +424,8 @@ int dpif_get_dp_stats(const struct dpif *, struct dpif_dp_stats *);
 
 const char *dpif_port_open_type(const char *datapath_type,
                                 const char *port_type);
-int dpif_port_add(struct dpif *, struct netdev *, uint32_t *port_nop);
-int dpif_port_del(struct dpif *, uint32_t port_no);
+int dpif_port_add(struct dpif *, struct netdev *, odp_port_t *port_nop);
+int dpif_port_del(struct dpif *, odp_port_t port_no);
 
 /* A port within a datapath.
  *
@@ -386,19 +433,18 @@ int dpif_port_del(struct dpif *, uint32_t port_no);
 struct dpif_port {
     char *name;                 /* Network device name, e.g. "eth0". */
     char *type;                 /* Network device type, e.g. "system". */
-    uint32_t port_no;           /* Port number within datapath. */
+    odp_port_t port_no;         /* Port number within datapath. */
 };
 void dpif_port_clone(struct dpif_port *, const struct dpif_port *);
 void dpif_port_destroy(struct dpif_port *);
 bool dpif_port_exists(const struct dpif *dpif, const char *devname);
-int dpif_port_query_by_number(const struct dpif *, uint32_t port_no,
+int dpif_port_query_by_number(const struct dpif *, odp_port_t port_no,
                               struct dpif_port *);
 int dpif_port_query_by_name(const struct dpif *, const char *devname,
                             struct dpif_port *);
-int dpif_port_get_name(struct dpif *, uint32_t port_no,
+int dpif_port_get_name(struct dpif *, odp_port_t port_no,
                        char *name, size_t name_size);
-int dpif_get_max_ports(const struct dpif *);
-uint32_t dpif_port_get_pid(const struct dpif *, uint32_t port_no);
+uint32_t dpif_port_get_pid(const struct dpif *, odp_port_t port_no);
 
 struct dpif_port_dump {
     const struct dpif *dpif;
@@ -431,7 +477,7 @@ struct dpif_flow_stats {
     uint64_t n_packets;
     uint64_t n_bytes;
     long long int used;
-    uint8_t tcp_flags;
+    uint16_t tcp_flags;
 };
 
 void dpif_flow_stats_extract(const struct flow *, const struct ofpbuf *packet,
@@ -475,7 +521,8 @@ int dpif_flow_dump_done(struct dpif_flow_dump *);
 int dpif_execute(struct dpif *,
                  const struct nlattr *key, size_t key_len,
                  const struct nlattr *actions, size_t actions_len,
-                 const struct ofpbuf *);
+                 const struct ofpbuf *,
+                 bool needs_help);
 \f
 /* Operation batching interface.
  *
@@ -513,11 +560,21 @@ struct dpif_flow_del {
 };
 
 struct dpif_execute {
+    /* Raw support for execute passed along to the provider. */
     const struct nlattr *key;       /* Partial flow key (only for metadata). */
     size_t key_len;                 /* Length of 'key' in bytes. */
     const struct nlattr *actions;   /* Actions to execute on packet. */
     size_t actions_len;             /* Length of 'actions' in bytes. */
     const struct ofpbuf *packet;    /* Packet to execute. */
+
+    /* Some dpif providers do not implement every action.  The Linux kernel
+     * datapath, in particular, does not implement ARP field modification.
+     *
+     * If this member is set to true, the dpif layer executes in userspace all
+     * of the actions that it can, and for OVS_ACTION_ATTR_OUTPUT and
+     * OVS_ACTION_ATTR_USERSPACE actions it passes the packet through to the
+     * dpif implementation. */
+    bool needs_help;
 };
 
 struct dpif_op {