<?xml version="1.0" encoding="US-ASCII"?>
<!DOCTYPE rfc SYSTEM "rfc2629.dtd">
<?rfc toc="yes"?>
<?rfc tocompact="yes"?>
<?rfc tocdepth="3"?>
<?rfc tocindent="yes"?>
<?rfc symrefs="yes"?>
<?rfc sortrefs="yes"?>
<?rfc comments="yes"?>
<?rfc inline="yes"?>
<?rfc compact="yes"?>
<?rfc subcompact="no"?>
<rfc category="info" docName="draft-pfaff-ovsdb-proto-03" ipr="trust200902">
  <front>
    <title abbrev="OVSDB Config Protocol">The Open vSwitch Database Management
    Protocol</title>

    <author fullname="Ben Pfaff" initials="B." surname="Pfaff">
      <organization>VMware, Inc.</organization>

      <address>
        <postal>
          <street>3401 Hillview Ave.</street>

          <!-- Reorder these if your country does things differently -->

          <city>Palo Alto</city>

          <region>CA</region>

          <code>94304</code>

          <country>USA</country>
        </postal>

        <email>blp@nicira.com</email>

        <!-- uri and facsimile elements may also be added -->
      </address>
    </author>

    <author fullname="Bruce Davie" initials="B." role="editor" surname="Davie">
      <organization>VMware, Inc.</organization>

      <address>
        <postal>
          <street>3401 Hillview Ave.</street>

          <!-- Reorder these if your country does things differently -->

          <city>Palo Alto</city>

          <region>CA</region>

          <code>94304</code>

          <country>USA</country>
        </postal>

        <email>bsd@nicira.com</email>

        <!-- uri and facsimile elements may also be added -->
      </address>
    </author>

    <date day="10" month="September" year="2013"/>

    <abstract>
      <t>Open vSwitch is an open source software switch designed to be used as
      a vswitch (virtual switch) in virtualized server environments. A vswitch
      forwards traffic between different virtual machines (VMs) on the same
      physical host and also forwards traffic between VMs and the physical
      network. Open vSwitch is open to programmatic extension and control
      using OpenFlow and the OVSDB (Open vSwitch Database) management
      protocol. This document defines the OVSDB management protocol.</t>
    </abstract>
  </front>

  <middle>
    <section anchor="intro" title="Introduction">
      <t>In virtualized server environments, it is typically required to use a
      vswitch (virtual switch) to forward traffic between different virtual
      machines (VMs) on the same physical host, and between VMs and the
      physical network. Open vSwitch <xref target="OVS"/> is an open source
      software switch designed to be used as a vswitch in such environments.
      Open vSwitch (OVS) is open to programmatic extension and control using
      OpenFlow <xref target="OF-SPEC"/> and the OVSDB (Open vSwitch Database)
      management protocol. This document defines the OVSDB management
      protocol.</t>

      <t>The OVSDB management protocol uses JSON<xref target="RFC4627"/> for
      its wire format, and is based on JSON-RPC version 1.0 <xref
      target="JSON-RPC"/>.</t>

      <t>The schema of the Open vSwitch database is documented in <xref
      target="DB-SCHEMA"/>. This document specifies the protocol for
      interacting with that database for the purposes of managing and
      configuring Open vSwitch instances. The protocol specified in this
      document also provides means for discovering the schema in use, as
      described in <xref target="get_schema"/>.</t>

      <section title="Requirements Language">
        <t>The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
        "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this
        document are to be interpreted as described in<xref
        target="RFC2119"/>.</t>
      </section>

      <section title="Terminology">
        <t><list style="empty">
            <t>UUID: Universally Unique Identifier. A 128-bit identifier that
            is unique in space and time <xref target="DCE"> </xref>.</t>

            <t>OVS: Open vSwitch. An open source virtual switch.</t>

            <t>OVSDB: The database that is used for the purpose of configuring
            OVS instances.</t>

            <t>JSON: Javascript Object Notation <xref target="RFC4627"/>.</t>

            <t>JSON-RPC: JSON Remote Procedure Call <xref
            target="JSON-RPC"/>.</t>

            <t>Durable: Reliably written to non-volatile storage (e.g. disk).
            OVSDB supports the option to specify whether transactions are
            durable or not. </t>
          </list></t>

        <t>Note that the JSON specification <xref target="RFC4627"> </xref>
        provides precise definitions of a number of important terms such as
        JSON values, objects, arrays, numbers, and strings. In all cases, this
        document uses the definitions from <xref target="RFC4627">
        </xref>.</t>
      </section>
    </section>

    <section anchor="system" title="System Overview">
      <t><xref target="OVS-int"/> illustrates the main components of Open
      vSwitch and the interfaces to a control and management cluster. An OVS
      instance comprises a database server (ovsdb-server), a vswitch daemon
      (ovs-vswitchd), and, optionally, a module that performs fast path
      forwarding. The "management and control cluster" consists of some number
      of managers and controllers. Managers use the OVSDB management protocol
      to manage OVS instances. An OVS instance is managed by at least one
      manager. Controllers use OpenFlow to install flow state in OpenFlow
      switches. An OVS instance can support multiple logical datapaths,
      referred to as bridges. There is at least one controller for each
      OpenFlow bridge.</t>

      <t>The OVSDB management interface is used to perform management and
      configuration operations on the OVS instance. Compared to OpenFlow,
      OVSDB management operations occur at a relatively long timescale.
      Examples of operations that are supported by OVSDB include:</t>

      <t><list style="symbols">
          <t>Creation, modification and deletion of OpenFlow datapaths
          (bridges), of which there may be many in a single OVS instance;</t>

          <t>Configuration of the set of controllers to which an OpenFlow
          datapath should connect;</t>

          <t>Configuration of the set of managers to which the OVSDB server
          should connect;</t>

          <t>Creation, modification and deletion of ports on OpenFlow
          datapaths;</t>

          <t>Creation, modification and deletion of tunnel interfaces on
          OpenFlow datapaths;</t>

          <t>Creation, modification and deletion of queues;</t>

          <t>Configuration of QoS (quality of service) policies, and
          attachment of those policies to queues;</t>

          <t>Collection of statistics.</t>
        </list>OVSDB does not perform per-flow operations, leaving those
      instead to OpenFlow.</t>

      <figure anchor="OVS-int" title="Open vSwitch Interfaces">
        <artwork><![CDATA[

       +----------------------+
       |      Control &       |
       |     Management       |
       |      Cluster         |
       +----------------------+
          |                \
          | OVSDB           \ OpenFlow
          | Mgmt             \
          |                   \
    +============================================+
    | +--------------+       +--------------+    |
    | |              |       |              |    |
    | | ovsdb-server |-------| ovs-vswitchd |    |
    | |              |       |              |    |
    | +--------------+       +--------------+    |
    |                               |            |
    |                        +----------------+  |
    |                        | Forwarding Path|  |
    |                        +----------------+  |
    +============================================+
       ]]></artwork>
      </figure>

      <t/>

      <t>Further information about the usage of the OVSDB management protocol
      is provided in <xref target="DB-SCHEMA"/>.</t>
    </section>

    <section title="OVSDB Structure">
      <t>This section outlines the overall structure of databases in OVSDB. As
      described here, the database is reasonably generic. For the complete and
      current description of the database schema as used in OVS, refer to
      <xref target="DB-SCHEMA"/>. See also <xref target="get_schema"/> for
      information on how the OVSDB protocol may be used to discover the schema
      currently in use.</t>

      <section title="JSON Usage">
        <t>OVSDB uses JSON <xref target="RFC4627"/> for both its schema format
        and its wire protocol format. The JSON implementation in Open vSwitch
        has the following limitations:<list style="symbols">
            <t>Null bytes (\u0000) SHOULD NOT be used in strings.</t>

            <t>Only UTF-8 encoding is supported.</t>
          </list></t>

        <t>The descriptions below use the following shorthand notations for
        JSON values. Terminology follows <xref target="RFC4627"/>. <list
            style="empty">
            <t>&lt;string&gt; A JSON string. Any Unicode string is allowed.
            Implementations SHOULD disallow null bytes.</t>

            <t>&lt;id&gt; A JSON string matching [a-zA-Z_][a-zA-Z0-9_]*.
            &lt;id&gt;s that begin with _ are reserved to the implementation
            and MUST NOT be used by the user.</t>

            <t>&lt;version&gt; A JSON string that contains a version number
            that matches [0-9]+\.[0-9]+\.[0-9]+</t>

            <t>&lt;boolean&gt; A JSON true or false value.</t>

            <t>&lt;number&gt; A JSON number.</t>

            <t>&lt;integer&gt; A JSON number with an integer value, within the
            range -(2**63)...+(2**63)-1.</t>

            <t>&lt;json-value&gt; Any JSON value.</t>

            <t>&lt;nonnull-json-value&gt; Any JSON value except null.</t>

            <t>&lt;error&gt; A JSON object with the following members: <figure>
                <artwork><![CDATA[
                "error": <string>          required
                "details": <string>        optional
		     ]]></artwork>
              </figure> <list style="empty">
                <t>The value of the "error" member is a short string,
                specified in this document, that broadly indicates the class
                of the error. Most "error" strings are specific to contexts
                described elsewhere in this document, but the following
                "error" strings may appear in any context where an
                &lt;error&gt; is permitted:</t>

                <t>"error": "resources exhausted" The operation requires more
                resources (memory, disk, CPU, etc.) than are currently
                available to the database server.</t>

                <t>"error": "I/O error" Problems accessing the disk, network,
                or other required resources prevented the operation from
                completing.</t>

                <t>Database implementations MAY use "error" strings not
                specified in this document to indicate errors that do not fit
                into any of the specified categories. Optionally, an
                &lt;error&gt; MAY include a "details" member, whose value is a
                string that describes the error in more detail for the benefit
                of a human user or administrator. This document does not
                specify the format or content of the "details" string. An
                &lt;error&gt; MAY also have other members that describe the
                error in more detail. This document does not specify the names
                or values of these members.</t>
              </list></t>
          </list></t>
      </section>

      <section anchor="schema-format" title="Schema Format">
        <t>An Open vSwitch configuration database consists of a set of tables,
        each of which has a number of columns and zero or more rows. A schema
        for the database is represented by &lt;database-schema&gt;, as
        described below. <list style="hanging">
            <t hangText="&lt;database-schema&gt;"><vspace/>A JSON object with
            the following members:</t>
          </list></t>

        <figure>
          <artwork><![CDATA[
        "name": <id>                            required
        "version": <version>                    required
        "cksum": <string>                       optional
        "tables": {<id>: <table-schema>, ...}   required
	
	    ]]></artwork>
        </figure>

        <t><list style="empty">
            <t hangText="">The "name" identifies the database as a whole. It
            must be provided to most JSON-RPC requests to identify the
            database being operated on. The value of "tables" is a JSON object
            whose names are table names and whose values are
            &lt;table-schema&gt;s.</t>

            <t hangText="">The "version" reports the version of the database
            schema. It is REQUIRED to be present. Open vSwitch semantics for
            "version" are described in <xref target="DB-SCHEMA"/>. Other
            schemas may use it differently.</t>

            <t hangText="">The "cksum" optionally reports an
            implementation-defined checksum for the database schema. Its use
            is primarily as a tool for schema developers, and clients SHOULD
            ignore it.</t>

            <t hangText="">The value of "tables" is a JSON object whose names
            are table names and whose values are &lt;table-schema&gt;s.</t>
          </list></t>

        <t><list style="hanging">
            <t hangText="&lt;table-schema&gt;"><vspace/> A JSON object with
            the following members:</t>
          </list></t>

        <figure>
          <artwork><![CDATA[
      "columns": {<id>: <column-schema>, ...}   required
      "maxRows": <integer>                      optional
      "isRoot": <boolean>                       optional
      "indexes": [<column-set>*]                optional 
	
	    ]]></artwork>
        </figure>

        <t><list style="empty">
            <t>The value of "columns" is a JSON object whose names are column
            names and whose values are &lt;column-schema&gt;s.</t>

            <t>Every table has the following columns whose definitions are not
            included in the schema:</t>

            <t><list style="empty">
                <t>"_uuid": This column, which contains exactly one UUID
                value, is initialized to a random value by the database engine
                when it creates a row. It is read-only, and its value never
                changes during the lifetime of a row.</t>

                <t>"_version": Like "_uuid", this column contains exactly one
                UUID value, initialized to a random value by the database
                engine when it creates a row, and it is read-only. However,
                its value changes to a new random value whenever any other
                field in the row changes. Furthermore, its value is ephemeral:
                when the database is closed and reopened, or when the database
                process is stopped and then started again, each "_version"
                also changes to a new random value.</t>
              </list>If "maxRows" is specified, as a positive integer, it
            limits the maximum number of rows that may be present in the
            table. This is a "deferred" constraint, enforced only at
            transaction commit time (see the "transact" request below). If
            "maxRows" is not specified, the size of the table is limited only
            by the resources available to the database server. "maxRows"
            constraints are enforced after unreferenced rows are deleted from
            tables with a false "isRoot".</t>

            <t>The "isRoot" boolean is used to determine whether rows in the
            table require strong references from other rows to avoid garbage
            collection. (See the discussion of "strong" and "weak" references
            below in the description of base types.) If "isRoot" is specified
            as true, then rows in the table exist independent of any
            references (they can be thought of as part of the "root set" in a
            garbage collector). If "isRoot" is omitted or specified as false,
            then any given row in the table may exist only when there is at
            least one reference to it, with refType "strong", from a different
            row (in the same table or a different table). This is a "deferred"
            action: unreferenced rows in the table are deleted just before
            transaction commit.</t>

            <t>For compatibility with schemas created before "isRoot" was
            introduced, if "isRoot" is omitted or false in every
            &lt;table-schema&gt; in a given &lt;database-schema&gt;, then
            every table is part of the root set.</t>

            <t>If "indexes" is specified, it must be an array of zero or more
            &lt;column-set&gt;s. A &lt;column-set&gt; is an array of one or
            more strings, each of which names a column. Each
            &lt;column-set&gt; is a set of columns whose values, taken
            together within any given row, must be unique within the table.
            This is a "deferred" constraint, enforced only at transaction
            commit time, after unreferenced rows are deleted and dangling weak
            references are removed. Ephemeral columns may not be part of
            indexes.</t>
          </list></t>

        <t><list style="hanging">
            <t hangText="&lt;column-schema&gt;"><vspace/>A JSON object with
            the following members:</t>
          </list></t>

        <figure>
          <artwork><![CDATA[
      "type": <type>                            required
      "ephemeral": <boolean>                    optional
      "mutable": <boolean>                      optional
	]]></artwork>
        </figure>

        <t><list style="empty">
            <t>The "type" specifies the type of data stored in this
            column.</t>

            <t>If "ephemeral" is specified as true, then this column's values
            are not guaranteed to be durable; they may be lost when the
            database restarts. A column whose type (either key or value) is a
            strong reference to a table that is not part of the root set is
            always durable, regardless of this value. (Otherwise, restarting
            the database could lose entire rows.)</t>

            <t>If "mutable" is specified as false, then this column's values
            may not be modified after they are initially set with the "insert"
            operation.</t>

            <t/>
          </list></t>

        <t><list style="hanging">
            <t hangText="&lt;type&gt;"><vspace/>The type of a database column.
            Either an &lt;atomic-type&gt; or a JSON object that describes the
            type of a database column, with the following members:</t>
          </list></t>

        <figure>
          <artwork><![CDATA[
      "key": <base-type>                 required
      "value": <base-type>               optional
      "min": <integer>                   optional
      "max": <integer> or "unlimited"    optional
	]]></artwork>
        </figure>

        <t><list style="empty">
            <t>If "min" or "max" is not specified, each defaults to 1. If
            "max" is specified as "unlimited", then there is no specified
            maximum number of elements, although the implementation will
            enforce some limit. After considering defaults, "min" must be
            exactly 0 or exactly 1, "max" must be at least 1, and "max" must
            be greater than or equal to "min".</t>

            <t>If "min" and "max" are both 1 and "value" is not specified, the
            type is the scalar type specified by "key".</t>

            <t>If "min" is not 1 or "max" is not 1, or both, and "value" is
            not specified, the type is a set of scalar type "key".</t>

            <t>If "value" is specified, the type is a map from type "key" to
            type "value".</t>
          </list><list style="hanging">
            <t hangText="&lt;base-type&gt;"><vspace/>The type of a key or
            value in a database column. Either an &lt;atomic-type&gt; or a
            JSON object with the following members:</t>
          </list></t>

        <figure>
          <artwork><![CDATA[
      "type": <atomic-type>            required
      "enum": <value>                  optional
      "minInteger": <integer>          optional, integers only
      "maxInteger": <integer>          optional, integers only
      "minReal": <real>                optional, reals only
      "maxReal": <real>                optional, reals only
      "minLength": <integer>           optional, strings only
      "maxLength": <integer>           optional, strings only
      "refTable": <id>                 optional, uuids only
      "refType": "strong" or "weak"    optional, only with "refTable"
	]]></artwork>
        </figure>

        <t><list style="empty">
            <t>An &lt;atomic-type&gt; by itself is equivalent to a JSON object
            with a single member "type" whose value is the
            &lt;atomic-type&gt;.</t>

            <t>"enum" may be specified as a &lt;value&gt; whose type is a set
            of one or more values specified for the member "type". If "enum"
            is specified, then the valid values of the &lt;base-type&gt; are
            limited to those in the &lt;value&gt;.</t>

            <t>"enum" is mutually exclusive with the following
            constraints.</t>

            <t>If "type" is "integer", then "minInteger" or "maxInteger" or
            both may also be specified, restricting the valid integer range.
            If both are specified, then the maxInteger must be greater than or
            equal to minInteger.</t>

            <t>If "type" is "real", then "minReal" or "maxReal" or both may
            also be specified, restricting the valid real range. If both are
            specified, then the maxReal must be greater than or equal to
            minReal.</t>

            <t>If "type" is "string", then "minLength" and "maxLength" or both
            may be specified, restricting the valid length of value strings.
            If both are specified, then maxLength must be greater than or
            equal to minLength. String length is measured in characters.</t>

            <t>If "type" is "uuid", then "refTable", if present, must be the
            name of a table within this database. If "refTable" is specified,
            then "refType" may also be specified. If "refTable" is set, the
            effect depends on "refType":</t>

            <t><list style="symbols">
                <t>If "refType" is "strong" or if "refType" is omitted, the
                allowed UUIDs are limited to UUIDs for rows in the named
                table.</t>

                <t>If "refType" is "weak", then any UUIDs are allowed, but
                UUIDs that do not correspond to rows in the named table will
                be automatically deleted. When this situation arises in a map,
                both the key and the value will be deleted from the map.</t>
              </list>"refTable" constraints are "deferred" constraints: they
            are enforced only at transaction commit time (see the "transact"
            request below). The other constraints on &lt;base-type&gt; are
            "immediate", enforced immediately by each operation.</t>
          </list> <list style="hanging">
            <t hangText="&lt;atomic-type&gt;"><vspace/>One of the strings
            "integer", "real", "boolean", "string", or "uuid", representing
            the specified scalar type.</t>
          </list></t>
      </section>
    </section>

    <section title="Wire Protocol">
      <t>The database wire protocol is implemented in JSON-RPC 1.0 <xref
      target="JSON-RPC"/>. While the spec of JSON-RPC allows a range of
      transports, implementations of this specification SHOULD operate
      directly over TCP. See <xref target="IANA"/> for discussion of the TCP
      port.</t>

      <section title="RPC Methods">
        <t>The following subsections describe the RPC methods that are
        supported. As described in the JSON-RPC 1.0 specification, each
        request comprises a string containing the name of the method, a
        (possibly null) array of parameters to pass to the method, and a
        request ID, which can be used to match the response to the request.
        Each response comprises a result object (non-null in the event of a
        successful invocation), an error object (non-null in the event of an
        error), and the ID of the matching request. More details on each
        method, its parameters and results are described below.</t>

        <t>An OVSDB server MUST implement all of the following methods. An
        OVSDB client MUST implement the "Echo" method, and is otherwise free
        to implement whichever methods suit the implementation's needs.</t>

        <t>The operations that may be performed on the OVS database using
        these methods (e.g., the "Transact" method) are described in <xref
        target="dbops"/>.</t>

        <section title="List Databases">
          <t>This operation retrieves an array whose elements are the names of
          the databases that can be accessed over this management protocol
          connection.</t>

          <t>The request object contains the following members:</t>

          <t><list style="symbols">
              <t>"method": "list_dbs"</t>

              <t>"params": []</t>

              <t>"id": &lt;nonnull-json-value&gt;</t>
            </list>The response object contains the following members:</t>

          <t><list style="symbols">
              <t>"result": [&lt;db-name&gt;,...]</t>

              <t>"error": null</t>

              <t>"id": same "id" as request</t>
            </list></t>
        </section>

        <section anchor="get_schema" title="Get Schema">
          <t>This operation retrieves a &lt;database-schema&gt; that describes
          hosted database &lt;db-name&gt;.</t>

          <t>The request object contains the following members:<list
              style="symbols">
              <t>"method": "get_schema"</t>

              <t>"params": [&lt;db-name&gt;]</t>

              <t>"id": &lt;nonnull-json-value&gt;</t>
            </list></t>

          <t>The response object contains the following members:<list
              style="symbols">
              <t>"result": &lt;database-schema&gt;</t>

              <t>"error": null</t>

              <t>"id": same "id" as request</t>
            </list></t>

	    <t>In the event that the database named in the request does
          not exist, the server sends a JSON-RPC error response of the
          following form: <list style="symbols">
              <t>"result": null</t>

              <t>"error": "unknown database"</t>

              <t>"id": same "id" as request</t>
            </list></t>
        </section>

        <section anchor="transact" title="Transact">
          <t>This RPC method causes the database server to execute a series of
          operations in the specified order on a given database.</t>

          <t>The request object contains the following members:</t>

          <t><list style="symbols">
              <t>"method": "transact"</t>

              <t>"params": [&lt;db-name&gt;, &lt;operation&gt;*]</t>

              <t>"id": &lt;nonnull-json-value&gt;</t>
            </list></t>

          <t>The value of "id" MUST be unique among all in-flight transactions
          within the current JSON-RPC session. Otherwise, the server may
          return a JSON-RPC error.</t>

          <t>The "params" array for this method consists of a &lt;db-name&gt;
          that identifies the database to which the transaction applies,
          followed by zero or more JSON objects, each of which represents a
          single database operation. <xref target="dbops"/> describes the
          valid operations. The database server executes each of the specified
          operations in the specified order, except that if an operation
          fails, then the remaining operations are not executed. The set of
          operations is executed as a single atomic, consistent, isolated
          transaction. The transaction is committed if and only if every
          operation succeeds. Durability of the commit is not guaranteed
          unless the "commit" operation, with "durable" set to true, is
          included in the operation set. See <xref target="dbops"/> for more
          discussion of the database operations.</t>

          <t>The response object contains the following members:</t>

          <t><list style="symbols">
              <t>"result": [&lt;object&gt;*]</t>

              <t>"error": null</t>

              <t>"id": same "id" as request</t>
            </list></t>

          <t>Regardless of whether errors occur in the database operations,
          the response is always a JSON-RPC response with null "error" and a
          "result" member that is an array with the same number of elements as
          "params". Each element of the "result" array corresponds to the same
          element of the "params" array. The "result" array elements may be
          interpreted as follows:</t>

          <t><list style="symbols">
              <t>A JSON object that does not contain an "error" member
              indicates that the operation completed successfully. The
              specific members of the object are specified below in the
              descriptions of individual operations. Some operations do not
              produce any results, in which case the object will have no
              members.</t>

              <t>An &lt;error&gt; indicates that the matching operation
              completed with an error.</t>

              <t>A JSON null value indicates that the operation was not
              attempted because a prior operation failed.</t>
            </list></t>

          <t>In general, "result" contains some number of successful results,
          possibly followed by an error, in turn followed by enough JSON null
          values to match the number of elements in "params". There is one
          exception: if all of the operations succeed, but the results cannot
          be committed, then "result" will have one more element than
          "params", with the additional element being an &lt;error&gt;. In
          this case, the possible "error" strings include the following:</t>

          <t><list style="empty">
              <t>"error": "referential integrity violation"</t>

              <t hangText="- ">When the commit was attempted, a column's value
              referenced the UUID for a row that did not exist in the table
              named by the column's &lt;base-type&gt; key or value "refTable"
              that has a "refType" of "strong". (This can be caused by
              inserting a row that references a nonexistent row, by deleting a
              row that is still referenced by another row, by specifying the
              UUID for a row in the wrong table, and other ways.)</t>

              <t hangText="- ">"error": "constraint violation"</t>

              <t hangText="- ">A number of situations can arise in which the
              attempted commit would lead to a constraint on the database
              being violated. (See <xref target="schema-format"/> for more
              discussion of constraints.) These situations include:<list
                  style="symbols">
                  <t>The number of rows in a table exceeds the maximum number
                  permitted by the table's "maxRows" value.</t>

                  <t>Two or more rows in a table had the same values in the
                  columns that comprise an index.</t>

                  <t>A column with a &lt;base-type&gt; key or value "refTable"
                  whose "refType" is "weak" became empty due to deletion(s),
                  and this column is not allowed to be empty because its
                  &lt;type&gt; has a "min" of 1. Such deletions may be the
                  result of rows that it referenced being deleted (or never
                  having existed, if the column's row was inserted within the
                  transaction).</t>
                </list></t>

              <t hangText="- ">"error": "resources exhausted"</t>

              <t hangText="- ">The operation requires more resources (memory,
              disk, CPU, etc.) than are currently available to the database
              server.</t>

              <t hangText="- ">"error": "I/O error"</t>

              <t hangText="- ">Problems accessing the disk, network, or other
              required resources prevented the operation from completing.</t>
            </list>If "params" contains one or more "wait" operations, then
          the transaction may take an arbitrary amount of time to complete.
          The database implementation MUST be capable of accepting, executing,
          and replying to other transactions and other JSON-RPC requests while
          a transaction or transactions containing "wait" operations are
          outstanding on the same or different JSON-RPC sessions.</t>
        </section>

        <section title="Cancel">
          <t>The "cancel" method is a JSON-RPC notification, i.e. no matching
          response is provided. It instructs the database server to
          immediately complete or cancel the "transact" request whose "id" is
          the same as the notification's "params" value. The notification
          object has the following members:<list style="symbols">
              <t>"method": "cancel"</t>

              <t>"params": [the "id" for an outstanding request]</t>

              <t>"id": null</t>
            </list></t>

          <t>If the "transact" request can be completed immediately, then the
          server sends a response in the form described for "transact", above
          (<xref target="transact"/>). Otherwise, the server sends a JSON-RPC
          error response of the following form: <list style="symbols">
              <t>"result": null</t>

              <t>"error": "canceled"</t>

              <t>"id": the "id" member of the canceled request.</t>
            </list>The "cancel" notification itself has no reply.</t>
        </section>

        <section title="Monitor">
          <t>The "monitor" request enables a client to replicate tables or
          subsets of tables within an OVSDB database by requesting
          notifications of changes to those tables and by receiving the
          complete initial state of a table or a subset of a table. The
          request object has the following members:</t>

          <t><list style="symbols">
              <t>"method": "monitor"</t>

              <t>"params": [&lt;db-name&gt;, &lt;json-value&gt;,
              &lt;monitor-requests&gt;]</t>

              <t>"id": &lt;nonnull-json-value&gt;</t>
            </list>The &lt;json-value&gt; parameter is used to match
          subsequent update notifications (see below) to this request. The
          &lt;monitor-requests&gt; object maps the name of the table to be
          monitored to an array of &lt;monitor-request&gt; objects.</t>

          <t>Each &lt;monitor-request&gt; is an object with the following
          members:</t>

          <figure>
            <artwork><![CDATA[    "columns": [<column>*]            optional
    "select": <monitor-select>        optional]]></artwork>
          </figure>

          <t>The columns, if present, define the columns within the table to
          be monitored. &lt;monitor-select&gt; is an object with the following
          members:</t>

          <figure>
            <artwork><![CDATA[    "initial": <boolean>              optional
    "insert": <boolean>               optional
    "delete": <boolean>               optional
    "modify": <boolean>               optional]]></artwork>
          </figure>

          <t>The contents of this object specify how the columns or table are
          to be monitored, as explained in more detail below.</t>

          <t>The response object has the following members:</t>

          <t><list style="symbols">
              <t>"result": &lt;table-updates&gt;</t>

              <t>"error": null</t>

              <t>"id": same "id" as request</t>
            </list>The &lt;table-updates&gt; object is described in detail in
          <xref target="update"/>. It contains the contents of the tables for
          which "initial" rows are selected. If no tables' initial contents
          are requested, then "result" is an empty object.</t>

          <t>Subsequently, when changes to the specified tables are committed,
          the changes are automatically sent to the client using the "update"
          monitor notification (see <xref target="update"/>). This monitoring
          persists until the JSON-RPC session terminates or until the client
          sends a "monitor_cancel" JSON-RPC request.</t>

          <t>Each &lt;monitor-request&gt; specifies one or more columns and
          the manner in which the columns (or the entire table) are to be
          monitored. The "columns" member specifies the columns whose values
          are monitored. It MUST NOT contain duplicates. If "columns" is
          omitted, all columns in the table, except for "_uuid", are
          monitored. The circumstances in which an "update" notification is
          sent for a row within the table are determined by
          &lt;monitor-select&gt;:<list style="symbols">
              <t>If "initial" is omitted or true, every row in the table is
              sent as part of the response to the "monitor" request.</t>

              <t>If "insert" is omitted or true, "update" notifications are
              sent for rows newly inserted into the table.</t>

              <t>If "delete" is omitted or true, "update" notifications are
              sent for rows deleted from the table.</t>

              <t>If "modify" is omitted or true, "update" notifications are
              sent whenever a row in the table is modified.</t>
            </list></t>

          <t>If there is more than one &lt;monitor-request&gt; in an array of
          them, then each &lt;monitor-request&gt; in the array should specify
          both "columns" and "select", and the "columns" MUST be
          non-overlapping sets.</t>
        </section>

        <section anchor="update" title="Update Notification">
          <t>The "update" notification is sent by the server to the client to
          report changes in tables that are being monitored following a
          "monitor" request as described above. The notification has the
          following members:</t>

          <t><list style="symbols">
              <t>"method": "update"</t>

              <t>"params": [&lt;json-value&gt;, &lt;table-updates&gt;]</t>

              <t>"id": null</t>
            </list>The &lt;json-value&gt; in "params" is the same as the value
          passed as the &lt;json-value&gt; in "params" for the corresponding
          "monitor" request. &lt;table-updates&gt; is an object that maps from
          a table name to a &lt;table-update&gt;. A &lt;table-update&gt; is an
          object that maps from the row's UUID to a &lt;row-update&gt; object.
          A &lt;row-update&gt; is an object with the following members:</t>

          <figure>
            <artwork><![CDATA[    "old": <row>   present for "delete" and "modify" updates
    "new": <row>   present for "initial", "insert", and "modify" updates
]]></artwork>
          </figure>

          <t/>

          <t>The format of &lt;row&gt; is described in <xref
          target="notation"/>.</t>

          <t>Each table in which one or more rows has changed (or whose
          initial view is being presented) is represented in "updates". Each
          row that has changed (or whose initial view is being presented) is
          represented in its &lt;table-update&gt; as a member with its name
          taken from the row's _uuid member. The corresponding value is a
          &lt;row-update&gt;: <list style="symbols">
              <t>The "old" member is present for "delete" and "modify"
              updates. For "delete" updates, each monitored column is
              included. For "modify" updates, the prior value of each
              monitored column whose value has changed is included (monitored
              columns that have not changed are represented in "new").</t>

              <t>The "new" member is present for "initial", "insert", and
              "modify" updates. For "initial" and "insert" updates, each
              monitored column is included. For "modify" updates, the new
              value of each monitored column is included.</t>
            </list>Note that initial views of rows are not presented in update
          notifications, but in the response object to the monitor request.
          The formatting of the &lt;table-updates&gt; object is the same in
          either case however.</t>
        </section>

        <section title="Monitor Cancellation">
          <t>The "monitor_cancel" request cancels a previously issued monitor
          request. The request object members are:</t>

          <t><list style="symbols">
              <t>"method": "monitor_cancel"</t>

              <t>"params": [&lt;json-value&gt;]</t>

              <t>"id": &lt;nonnull-json-value&gt;</t>
            </list>The &lt;json-value&gt; in "params" matches the
          &lt;json-value&gt; in "params" for the ongoing "monitor" request
          that is to be canceled. No more "update" messages will be sent for
          this table monitor. The response to this request has the following
          members:</t>

          <t><list style="symbols">
              <t>"result": {}</t>

              <t>"error": null</t>

              <t>"id": the request "id" member</t>
            </list>In the event that a monitor cancellation request refers to
          an unknown monitor request, an error response with the following
          members is returned:</t>

          <t><list style="symbols">
              <t>"result": null</t>

              <t>"error": "unknown monitor"</t>

              <t>"id": the request "id" member</t>
            </list></t>
        </section>

        <section title="Lock Operations">
          <t>Three RPC methods, "lock", "steal", and "unlock", provide support
          to clients to perform locking operations on the database. The
          database server supports an arbitrary number of locks, each of which
          is identified by a client-defined id. At any given time, each lock
          may have at most one owner. The precise usage of a lock is
          determined by the client. For example, a set of clients may agree
          that a certain table can only be written by the owner of a certain
          lock. OVSDB itself does not enforce any restrictions on how locks
          are used - it simply ensures that a lock has at most one owner.</t>

          <t>The RPC request objects have the following members:</t>

          <t><list style="symbols">
              <t>"method": "lock", "steal", or "unlock"</t>

              <t>"params": [&lt;id&gt;]</t>

              <t>"id": &lt;nonnull-json-value&gt;</t>
            </list>The response depends on the request, and has the following
          members:</t>

          <t><list style="symbols">
              <t>"result": {"locked": boolean} for "lock"</t>

              <t>"result": {"locked": true} for "steal"</t>

              <t>"result": {} for "unlock"</t>

              <t>"error": null</t>

              <t>"id": same "id" as request</t>
            </list>The three methods operate as follows:</t>

          <t><list style="symbols">
              <t>"lock": The database will assign this client ownership of the
              lock as soon as it becomes available. When multiple clients
              request the same lock, they will receive it in first-come, first
              served order.</t>

              <t>"steal": The database immediately assigns this client
              ownership of the lock. If there is an existing owner, it loses
              ownership.</t>

              <t>"unlock": If the client owns the lock, releases it. If the
              client has requested ownership of the lock, this cancels the
              request.<vspace blankLines="1"/>(Closing or otherwise
              disconnecting a database client connection unlocks all of its
              locks.)</t>
            </list>For any given lock, the client MUST alternate "lock" or
          "steal" operations with "unlock" operations. That is, if the
          previous operation on a lock was "lock" or "steal", it MUST be
          followed by an "unlock" operation, and vice versa.</t>

          <t>For a "lock" operation, the "locked" member in the response
          object is true if the lock has already been acquired, false if
          another client holds the lock and the client's request for it was
          queued. In the latter case, the client will be notified later with a
          "locked" message (<xref target="locked"/>) when acquisition
          succeeds.</t>

          <t>These requests complete and send a response quickly, without
          waiting. The "locked" and "stolen" notifications (see below) report
          asynchronous changes to ownership.</t>

          <t>Note that the scope of a lock is a database server, not a
          database hosted by that server. A client may choose to implement a
          naming convention, such as "&lt;db-name&gt;__&lt;lock-name&gt;",
          which can effectively limit the scope of a lock to a particular
          database.</t>
        </section>

        <section anchor="locked" title="Locked Notification">
          <t>The "locked" notification is provided to notify a client that it
          has been granted a lock it had previously request a lock with the
          "lock" method described above. The notification has the following
          members:</t>

          <t><list style="symbols">
              <t>"method": "locked"</t>

              <t>"params": [&lt;id&gt;]</t>

              <t>"id": null</t>
            </list>"Params" contains the name of the lock that was given in
          the "lock" request. The notified client now owns the lock named in
          "params".</t>

          <t>The database server sends this notification after the reply to
          the corresponding "lock" request (but only if the "locked" member of
          the response was false), and before the reply to the client's
          subsequent "unlock" request.</t>
        </section>

        <section anchor="stolen" title="Stolen Notification">
          <t>The "stolen" notification is provided to notify a client, which
          had previously obtained a lock, that another client has stolen
          ownership of that lock. The notification has the following
          members:</t>

          <t><list style="symbols">
              <t>"method": "stolen"</t>

              <t>"params": [&lt;id&gt;]</t>

              <t>"id": null</t>
            </list>The notified client no longer owns the lock named in
          "params". The client MUST still issue an "unlock" request before
          performing any subsequent "lock" or "steal" operation on the
          lock.</t>

          <t>If the client originally obtained the lock through a "lock"
          request, then it will automatically regain the lock later after the
          client that stole it releases it. (The database server will send the
          client a "locked" notification at that point to let it know.)</t>

          <t>If the client originally obtained the lock through a "steal"
          request, the database server won't automatically reassign it
          ownership of the lock when it later becomes available. To regain
          ownership, the client must "unlock" and then "lock" or "steal" the
          lock again.</t>
        </section>

        <section title="Echo">
          <t>The "echo" method can be used by both clients and servers to
          verify the liveness of a database connection. It MUST be implemented
          by both clients and servers. The members of the request are:</t>

          <t><list style="symbols">
              <t>"method": "echo"</t>

              <t>"params": JSON array with any contents</t>

              <t>"id": &lt;json-value&gt;</t>
            </list>The response object has the following members:</t>

          <t><list style="symbols">
              <t>"result": same as "params"</t>

              <t>"error": null</t>

              <t>"id": the request "id" member</t>
            </list></t>
        </section>
      </section>
    </section>

    <section anchor="dbops" title="Database Operations">
      <t>This section describes the operations that may be specified in the
      "transact" method described in <xref target="transact"/>.</t>

      <section anchor="notation" title="Notation">
        <t>We introduce the following notation for the discussion of
        operations. <list style="hanging">
            <t hangText=" &lt;db-name&gt;"><vspace/> An &lt;id&gt; that names
            a database. The valid &lt;db-name&gt;s can be obtained using a
            "list_dbs" request. The &lt;db-name&gt; is taken from the "name"
            member of &lt;database-schema&gt;.</t>

            <t hangText="&lt;table&gt;"><vspace/> An &lt;id&gt; that names a
            table.</t>

            <t hangText="&lt;column&gt;"><vspace/>An &lt;id&gt; that names a
            table column.</t>

            <t hangText="&lt;row&gt; "><vspace/>A JSON object that describes a
            table row or a subset of a table row. Each member is the name of a
            table column paired with the &lt;value&gt; of that column.</t>

            <t hangText="&lt;value&gt;"><vspace/>A JSON value that represents
            the value of a column in a table row, one of &lt;atom&gt;, a
            &lt;set&gt;, or a &lt;map&gt;.</t>

            <t hangText="&lt;atom&gt;"><vspace/>A JSON value that represents a
            scalar value for a column, one of &lt;string&gt;, &lt;number&gt;,
            &lt;boolean&gt;, &lt;uuid&gt;, &lt;named-uuid&gt;.</t>

            <t hangText="&lt;set&gt;"><vspace/>Either an &lt;atom&gt;,
            representing a set with exactly one element, or a 2-element JSON
            array that represents a database set value. The first element of
            the array must be the string "set" and the second element must be
            an array of zero or more &lt;atom&gt;s giving the values in the
            set. All of the &lt;atom&gt;s must have the same type.</t>

            <t hangText="&lt;map&gt;"><vspace/>A 2-element JSON array that
            represents a database map value. The first element of the array
            must be the string "map" and the second element must be an array
            of zero or more &lt;pair&gt;s giving the values in the map. All of
            the &lt;pair&gt;s must have the same key and value
            types.<vspace/>(JSON objects are not used to represent &lt;map&gt;
            because JSON only allows string names in an object.)</t>

            <t hangText="&lt;pair&gt;"><vspace/>A 2-element JSON array that
            represents a pair within a database map. The first element is an
            &lt;atom&gt; that represents the key, the second element is an
            &lt;atom&gt; that represents the value.</t>

            <t hangText="&lt;uuid&gt;"><vspace/> A 2-element JSON array that
            represents a UUID. The first element of the array must be the
            string "uuid" and the second element must be a 36-character string
            giving the UUID in the format described by RFC 4122. For example,
            the following &lt;uuid&gt; represents the UUID
            550e8400-e29b-41d4-a716-446655440000:<vspace blankLines="1"/>
            ["uuid", "550e8400-e29b-41d4-a716-446655440000"]</t>

            <t hangText="&lt;named-uuid&gt;"><vspace/>A 2-element JSON array
            that represents the UUID of a row inserted in an "insert"
            operation within the same transaction. The first element of the
            array must be the string "named-uuid" and the second element
            should be the &lt;id&gt; specified as the "uuid-name" for an
            "insert" operation within the same transaction. For example, if an
            "insert" operation within this transaction specifies a "uuid-name"
            of "myrow", the following &lt;named-uuid&gt; represents the UUID
            created by that operation: <vspace blankLines="1"/> ["named-uuid",
            "myrow"] <vspace blankLines="1"/>A &lt;named-uuid&gt; may be used
            anywhere a &lt;uuid&gt; is valid. This enables a single
            transaction to both insert a new row and then refer to that row
            using the "uuid-name" that was associated with that row when it
            was inserted. Note that the "uuid-name" is only meaningful within
            the scope of a single transaction.</t>

            <t hangText="&lt;condition&gt;"><vspace/> A 3-element JSON array
            of the form [&lt;column&gt;, &lt;function&gt;, &lt;value&gt;] that
            represents a test on a column value. Except as otherwise specified
            below, &lt;value&gt; MUST have the same type as &lt;column&gt;.
            The meaning depends on the type of &lt;column&gt;: <list
                style="hanging">
                <t hangText="integer or real"><vspace/>&lt;function&gt; must
                be "&lt;", "&lt;=", "==", "!=", "&gt;=", "&gt;", "includes",
                or "excludes". <vspace blankLines="1"/>The test is true if the
                column's value satisfies the relation &lt;function&gt;
                &lt;value&gt;, e.g. if the column has value 1 and
                &lt;value&gt; is 2, the test is true if &lt;function&gt; is
                "&lt;", "&lt;=" or "!=", but not otherwise. <vspace
                blankLines="1"/>"includes" is equivalent to "=="; "excludes"
                is equivalent to "!=".</t>

                <t
                hangText="boolean or string or uuid"><vspace/>&lt;function&gt;
                must be "!=", "==", "includes", or "excludes".<vspace
                blankLines="1"/>If &lt;function&gt; is "==" or "includes", the
                test is true if the column's value equals &lt;value&gt;. If
                &lt;function&gt; is "!=" or "excludes", the test is
                inverted.</t>

                <t hangText="set or map"><vspace/>&lt;function&gt; must be
                "!=", "==", "includes", or "excludes". <vspace
                blankLines="1"/>If &lt;function&gt; is "==", the test is true
                if the column's value contains exactly the same values (for
                sets) or pairs (for maps). If &lt;function&gt; is "!=", the
                test is inverted. <vspace blankLines="1"/>If &lt;function&gt;
                is "includes", the test is true if the column's value contains
                all of the values (for sets) or pairs (for maps) in
                &lt;value&gt;. The column's value may also contain other
                values or pairs. <vspace blankLines="1"/>If &lt;function&gt;
                is "excludes", the test is true if the column's value does not
                contain any of the values (for sets) or pairs (for maps) in
                &lt;value&gt;. The column's value may contain other values or
                pairs not in &lt;value&gt;. <vspace blankLines="1"/>If
                &lt;function&gt; is "includes" or "excludes", then the
                required type of &lt;value&gt; is slightly relaxed, in that it
                may have fewer than the minimum number of elements specified
                by the column's type. If &lt;function&gt; is "excludes", then
                the required type is additionally relaxed in that
                &lt;value&gt; may have more than the maximum number of
                elements specified by the column's type. &lt;function&gt; One
                of "&lt;", "&lt;=", "==", "!=", "&gt;=", "&gt;", "includes",
                "excludes".</t>
              </list></t>

            <t hangText="&lt;function&gt;"><vspace/>One of "&lt;", "&lt;=",
            "==", "!=", "&gt;=", "&gt;", "includes", "excludes".</t>

            <t hangText="&lt;mutation&gt; "><vspace/>A 3-element JSON array of
            the form [&lt;column&gt;, &lt;mutator&gt;, &lt;value&gt;] that
            represents a change to a column value. Except as otherwise
            specified below, &lt;value&gt; must have the same type as
            &lt;column&gt;. The meaning depends on the type of
            &lt;column&gt;:<list style="hanging">
                <t hangText="integer or real"><vspace/> &lt;mutator&gt; must
                be "+=", "-=", "*=", "/=" or (integer only) "%=". The value of
                &lt;column&gt; is changed to the sum, difference, product,
                quotient, or remainder, respectively, of &lt;column&gt; and
                &lt;value&gt;.<vspace blankLines="1"/> Constraints on
                &lt;column&gt; are ignored when parsing &lt;value&gt;.</t>

                <t hangText="boolean or string or uuid"><vspace/> No valid
                &lt;mutator&gt;s are currently defined for these types.</t>

                <t hangText="set "><vspace/>Any &lt;mutator&gt; valid for the
                set's element type may be applied to the set, in which case
                the mutation is applied to each member of the set
                individually. &lt;value&gt; must be a scalar value of the same
                type as the set's element type, except that constraints are
                ignored when parsing &lt;value&gt;. <vspace blankLines="1"/>If
                &lt;mutator&gt; is "insert", then each of the values in the
                set in &lt;value&gt; is added to &lt;column&gt; if it is not
                already present. The required type of &lt;value&gt; is
                slightly relaxed, in that it may have fewer than the minimum
                number of elements specified by the column's type. <vspace
                blankLines="1"/>If &lt;mutator&gt; is "delete", then each of
                the values in the set in &lt;value&gt; is removed from
                &lt;column&gt; if it is present there. The required type is
                slightly relaxed in that &lt;value&gt; may have more or less
                than the maximum number of elements specified by the column's
                type.</t>

                <t hangText="map"><vspace/> &lt;mutator&gt; must be "insert"
                or "delete". <vspace blankLines="1"/>If &lt;mutator&gt; is
                "insert", then each of the key-value pairs in the map in
                &lt;value&gt; is added to &lt;column&gt; only if its key is
                not already present. The required type of &lt;value&gt; is
                slightly relaxed, in that it may have fewer than the minimum
                number of elements specified by the column's type. <vspace
                blankLines="1"/>If &lt;mutator&gt; is "delete", then
                &lt;value&gt; may have the same type as &lt;column&gt; (a map
                type) or it may be a set whose element type is the same as
                &lt;column&gt;'s key type:<list style="symbols">
                    <t>If &lt;value&gt; is a map, the mutation deletes each
                    key-value pair in &lt;column&gt; whose key and value equal
                    one of the key-value pairs in &lt;value&gt;.</t>

                    <t>If &lt;value&gt; is a set, the mutation deletes each
                    key-value pair in &lt;column&gt; whose key equals one of
                    the values in &lt;value&gt;.</t>
                  </list> For "delete", &lt;value&gt; may have any number of
                elements, regardless of restrictions on the number of elements
                in &lt;column&gt;.</t>
              </list></t>

            <t hangText="&lt;mutator&gt; "><vspace/> One of "+=", "-=", "*=",
            "/=", "%=", "insert", "delete".</t>
          </list></t>
      </section>

      <section title="Operations">
        <t>The operations that may be performed as part of a "transact" RPC
        request (see <xref target="transact"/>) are described in the following
        sections. Each of these operations is a JSON object that may be
        included as one of the elements of the "params" array that is one of
        the elements of the "transact" request. The details of each object,
        its semantics, results, and possible errors are described below.</t>

        <section title="Insert">
          <t>The "insert" object contains the following members:</t>

          <figure>
            <artwork><![CDATA[    "op": "insert"          required
    "table": <table>        required
    "row": <row>            required
    "uuid-name": <id>       optional]]></artwork>
          </figure>

          <t>The corresponding result object contains the following
          member:<list style="empty">
              <t>"uuid": &lt;uuid&gt;</t>
            </list></t>

          <t>The operation inserts "row" into "table". If "row" does not
          specify values for all the columns in "table", those columns receive
          default values. The default value for a column depends on its type.
          The default for a column whose &lt;type&gt; specifies a "min" of 0
          is an empty set or empty map. Otherwise, the default is a single
          value or a single key-value pair, whose value(s) depend on its
          &lt;atomic-type&gt;:<list style="symbols">
              <t>"integer" or "real": 0</t>

              <t>"boolean": false</t>

              <t>"string": "" (the empty string)</t>

              <t>"uuid": 00000000-0000-0000-0000-000000000000</t>
            </list>The new row receives a new, randomly generated UUID. If
          "uuid-name" is supplied, then it is an error if &lt;id&gt; is not
          unique among the "uuid-name"s supplied on all the "insert"
          operations within this transaction. The UUID for the new row is
          returned as the "uuid" member of the result.</t>

          <t>The errors that may be returned are as follows:<list
              style="hanging">
              <t
              hangText=" &quot;error&quot;: &quot;duplicate uuid-name&quot;"><vspace/>
              The same "uuid-name" appears on another "insert" operation
              within this transaction.</t>

              <t
              hangText=" &quot;error&quot;: &quot;constraint violation&quot;"><vspace/>One
              of the values in "row" does not satisfy the immediate
              constraints for its column's &lt;base-type&gt;. This error will
              occur for columns that are not explicitly set by "row" if the
              default value does not satisfy the column's constraints.</t>
            </list></t>
        </section>

        <section title="Select">
          <t>The "select" object contains the following members:</t>

          <figure>
            <artwork><![CDATA[    "op": "select"          required
    "table": <table>        required
    "where": [<condition>*]       required
    "columns": [<column>*]        optional]]></artwork>
          </figure>

          <t>The corresponding result object contains the following
          member:<list style="empty">
              <t>"rows": [&lt;row&gt;*]</t>
            </list></t>

          <t>The operation searches "table" for rows that match all the
          conditions specified in "where". If "where" is an empty array, every
          row in "table" is selected.</t>

          <t>The "rows" member of the result is an array of objects. Each
          object corresponds to a matching row, with each column specified in
          "columns" as a member, the column's name as the member name and its
          value as the member value. If "columns" is not specified, all the
          table's columns are included (including the internally generated
          "_uuid" and "_version" columns). If two rows of the result have the
          same values for all included columns, only one copy of that row is
          included in "rows". Specifying "_uuid" within "columns" will avoid
          dropping duplicates, since every row has a unique UUID.</t>

          <t>The ordering of rows within "rows" is unspecified.</t>

          <t/>
        </section>

        <section title="Update">
          <t>The "update" object contains the following members:</t>

          <figure>
            <artwork><![CDATA[    "op": "update"          required
    "table": <table>        required
    "where": [<condition>*]       required
    "row": <row>                  required
]]></artwork>
          </figure>

          <t>The corresponding result object contains the following
          member:</t>

          <t><list style="empty">
              <t>"count": &lt;integer&gt;</t>
            </list>The operation updates rows in a table. It searches "table"
          for rows that match all the conditions specified in "where". For
          each matching row, it changes the value of each column specified in
          "row" to the value for that column specified in "row". The "_uuid"
          and "_version" columns of a table may not be directly updated with
          this operation. Columns designated read-only in the schema also may
          not be updated.</t>

          <t>The "count" member of the result specifies the number of rows
          that matched.</t>

          <t>The error that may be returned is:</t>

          <t><list style="hanging">
              <t
              hangText=" &quot;error&quot;: &quot;constraint violation&quot;"><vspace/>
              One of the values in "row" does not satisfy the immediate
              constraints for its column's &lt;base-type&gt;.</t>
            </list></t>
        </section>

        <section title="Mutate">
          <t>The "mutate" object contains the following members:</t>

          <figure>
            <artwork><![CDATA[    "op":  "mutate"               required
    "table": <table>              required
    "where": [<condition>*]       required
    "mutations": [<mutation>*]    required
]]></artwork>
          </figure>

          <t>The corresponding result object contains the following
          member:</t>

          <t><list style="empty">
              <t>"count": &lt;integer&gt;</t>
            </list>The operation mutates rows in a table. It searches "table"
          for rows that match all the conditions specified in "where". For
          each matching row, it mutates its columns as specified by each
          &lt;mutation&gt; in "mutations", in the order specified.</t>

          <t>The "_uuid" and "_version" columns of a table may not be directly
          modified with this operation. Columns designated read-only in the
          schema also may not be updated.</t>

          <t>The "count" member of the result specifies the number of rows
          that matched.</t>

          <t>The errors that may be returned are:</t>

          <t><list style="hanging">
              <t
              hangText=" &quot;error&quot;:  &quot;domain error&quot;"><vspace/>
              The result of the mutation is not mathematically defined, e.g.
              division by zero.</t>

              <t
              hangText=" &quot;error&quot;:  &quot;range error&quot;"><vspace/>The
              result of the mutation is not representable within the
              database's format, e.g. an integer result outside the range
              INT64_MIN...INT64_MAX or a real result outside the range
              -DBL_MAX...DBL_MAX.</t>

              <t
              hangText=" &quot;error&quot;: &quot;constraint violation&quot;"><vspace/>The
              mutation caused the column's value to violate a constraint, e.g.
              it caused a column to have more or fewer values than are
              allowed, an arithmetic operation caused a set or map to have
              duplicate elements, or it violated a constraint specified by a
              column's &lt;base-type&gt;.</t>
            </list></t>
        </section>

        <section title="Delete">
          <t>The "delete" object contains the following members:</t>

          <figure>
            <artwork><![CDATA[    "op":  "delete"               required
    "table": <table>              required
    "where": [<condition>*]       required
]]></artwork>
          </figure>

          <t>The corresponding result object contains the following
          member:</t>

          <t><list style="empty">
              <t>"count": &lt;integer&gt;</t>
            </list>The operation deletes all the rows from "table" that match
          all the conditions specified in "where". The "count" member of the
          result specifies the number of deleted rows.</t>

          <t/>
        </section>

        <section title="Wait">
          <t>The "wait" object contains the following members:</t>

          <figure>
            <artwork><![CDATA[    "op": "wait"                        required
    "timeout": <integer>                optional
    "table": <table>                    required
    "where": [<condition>*]             required
    "columns": [<column>*]              required
    "until": "==" or "!="               required
    "rows": [<row>*]                    required
]]></artwork>
          </figure>

          <t>There is no corresponding result object.</t>

          <t>The operation waits until a condition becomes true.</t>

          <t>If "until" is "==", it checks whether the query on "table"
          specified by "where" and "columns", which is evaluated in the same
          way as specified for "select", returns the result set specified by
          "rows". If it does, then the operation completes successfully.
          Otherwise, the entire transaction rolls back. It is automatically
          restarted later, after a change in the database makes it possible
          for the operation to succeed. The client will not receive a response
          until the operation permanently succeeds or fails.</t>

          <t>If "until" is "!=", the sense of the test is negated. That is, as
          long as the query on "table" specified by "where" and "columns"
          returns "rows", the transaction will be rolled back and restarted
          later.</t>

          <t>If "timeout" is specified, then the transaction aborts after the
          specified number of milliseconds. The transaction is guaranteed to
          be attempted at least once before it aborts. A "timeout" of 0 will
          abort the transaction on the first mismatch.</t>

          <t>The error that may be returned is:</t>

          <t><list style="hanging">
              <t
              hangText=" &quot;error&quot;:  &quot;timed out&quot;"><vspace/>
              The "timeout" was reached before the transaction was able to
              complete.</t>
            </list></t>
        </section>

        <section title="Commit">
          <t>The "commit" object contains the following members:</t>

          <figure>
            <artwork><![CDATA[    "op": "commit"                      required
    "durable": <boolean>                required
]]></artwork>
          </figure>

          <t>There is no corresponding result object.</t>

          <t>If "durable" is specified as true, then the transaction, if it
          commits, will be stored durably (to disk) before the reply is sent
          to the client. This operation with "durable" set to false is
          effectively a no-op.</t>

          <t>The error that may be returned is:</t>

          <t><list style="hanging">
              <t
              hangText=" &quot;error&quot;: &quot;not supported&quot;"><vspace/>
              When "durable" is true, this database implementation does not
              support durable commits.</t>
            </list></t>
        </section>

        <section title="Abort">
          <t>The "abort" object contains the following member:</t>

          <figure>
            <artwork><![CDATA[    "op":  "abort"                      required
]]></artwork>
          </figure>

          <t>There is no corresponding result object (the operation never
          succeeds).</t>

          <t>The operation aborts the entire transaction with an error. This
          may be useful for testing.</t>

          <t>The error that will be returned is:</t>

          <t><list style="hanging">
              <t hangText=" &quot;error&quot;: &quot; aborted&quot;"><vspace/>
              This operation always fails with this error.</t>
            </list></t>
        </section>

        <section title="Comment">
          <t>The "comment" object contains the following members:</t>

          <figure>
            <artwork><![CDATA[    "op": "comment"                    required
    "comment": <string>                required
]]></artwork>
          </figure>

          <t>There is no corresponding result object.</t>

          <t>The operation provides information to a database administrator on
          the purpose of a transaction. The ovsdb-server implementation, for
          example, adds comments in transactions that modify the database to
          the database journal. This can be helpful in debugging, e.g. when
          there are multiple clients writing to a database. An example of this
          can be seen in the ovs-vsctl tool, a command line tool that
          interacts with ovsdb-server. When performing operations on the
          database, it includes the command that was invoked (e.g. "ovs-vsctl
          add-br br0") as a comment in the transaction, which can then be seen
          in the journal alongside the changes that were made to the tables in
          the database.</t>
        </section>

        <section title="Assert">
          <t>The assert object contains the following members: </t>
	  <figure>
              <artwork><![CDATA[    "op": "assert"                     required
    "lock": <id>                       required]]></artwork>
            </figure>

          <t>Result object has no members.</t>

          <t>The assert operation causes the transaction to be aborted if the
          client does not own the lock named &lt;id&gt;.</t>

          <t>The error that may be returned is:</t>

          <t><list style="hanging">
              <t
              hangText=" &quot;error&quot;: &quot;not owner&quot;"><vspace/>
              The client does not own the named lock.</t>
            </list></t>
        </section>
      </section>
    </section>

    <section anchor="IANA" title="IANA Considerations">
      <t>IANA has assigned TCP port 6640 for this protocol. Earlier implementations 
      of OVSDB used another port number, but compliant implementations should use the
      IANA-assigned number.</t>

      <t>This document requires no further IANA action.</t>
    </section>

    <section anchor="Security" title="Security Considerations">
      <t>The main security issue that needs to be addressed for the OVSDB
      protocol is the authentication, integrity, and privacy of communications
      between a client and server implementing this protocol. To provide such
      protection, an OVSDB connection SHOULD be secured using Transport Layer
      Security (TLS) <xref target="RFC5246"/>. The precise details of how
      clients and servers authenticate each other is highly dependent on the
      operating environment. It is often the case that OVSDB clients and
      servers operate in a tightly controlled environment, e.g., on machines
      in a single data center where they communicate on an isolated management
      network.</t>
    </section>

    <section title="Acknowledgements">
      <t>Thanks to Jeremy Stribling and Justin Pettit for their helpful input
      to this document.</t>
    </section>
  </middle>

  <back>
    <references title="Normative References">
      <?rfc include='reference.RFC.2119'?>

      <?rfc include='reference.RFC.4627'?>

      <?rfc include='reference.RFC.5246'?>

      <reference anchor="JSON-RPC"
                 target="http://json-rpc.org/wiki/specification">
        <front>
          <title>JSON-RPC Specification, Version 1.0</title>

          <author/>

          <date/>
        </front>
      </reference>

      <reference anchor="DCE">
        <front>
          <title>DCE: Remote Procedure Call</title>

          <author>
            <organization/>
          </author>

          <date month="August" year="1994"/>
        </front>

        <seriesInfo name="Open Group CAE Specification" value="C309"/>

        <seriesInfo name="ISBN" value="1-85912-041-5"/>
      </reference>
    </references>

    <references title="Informative References">
      <reference anchor="OVS" target="http://openvswitch.org/">
        <front>
          <title>Open vSwitch</title>

          <author/>

          <date/>
        </front>
      </reference>

      <reference anchor="DB-SCHEMA"
                 target="http://openvswitch.org/ovs-vswitchd.conf.db.5.pdf/">
        <front>
          <title>Open vSwitch Database Schema</title>

          <author/>

          <date/>
        </front>
      </reference>

      <reference anchor="OF-SPEC"
                 target="https://www.opennetworking.org/images/stories/downloads/openflow/openflow-spec-v1.3.0.pdf">
        <front>
          <title>OpenFlow Switch Specification, version 1.3</title>

          <author/>

          <date/>
        </front>
      </reference>
    </references>
  </back>
</rfc>
