Skip to content

Commit

Permalink
nx-match: Add support for experimenter OXM.
Browse files Browse the repository at this point in the history
OpenFlow 1.2+ defines a means for vendors to define vendor-specific OXM
fields, called "experimenter OXM".  These OXM fields are expressed with a
64-bit OXM header instead of the 32-bit header used for standard OXM (and
NXM).  Until now, OVS has not implemented experimenter OXM, and indeed we
have had little need to do so because of a pair of special 32-bit OXM classes
grandfathered to OVS as part of the OpenFlow 1.2 standardization process.

However, I want to prototype a feature for OpenFlow 1.5 that uses an
experimenter OXM as part of the prototype, so to do this OVS needs to
support experimenter OXM.  This commit adds that support.

Most of this commit is a fairly straightforward change: it extends the type
used for OXM/NXM from 32 to 64 bits and adds code to encode and decode the
longer headers when necessary.  Some other changes are necessary because
experimenter OXMs have a funny idea of the division between "header" and
"body": the extra 32 bits for experimenter OXMs are counted as part of the body
rather than the header according to the OpenFlow standard (even though this
does not entirely make sense), so arithmetic in various places has to be
adjusted, which is the reason for the new functions nxm_experimenter_len(),
nxm_payload_len(), and nxm_header_len().

Another change that calls for explanation is the new function mf_nxm_header()
that has been split from mf_oxm_header().  This function is used in actions
where the space for an NXM or OXM header is fixed so that there is no room
for a 64-bit experimenter type.  An upcoming commit will add new variations
of these actions that can support experimenter OXM.

Testing experimenter OXM is tricky because I do not know of any in
widespread use.  Two ONF proposals use experimenter OXMs: EXT-256 and
EXT-233.  EXT-256 is not suitable to implement for testing because its use
of experimenter OXM is wrong and will be changed.  EXT-233 is not suitable
to implement for testing because it requires adding a new field to struct
flow and I am not yet convinced that that field and the feature that it
supports is worth having in Open vSwitch.  Thus, this commit assigns an
experimenter OXM code point to an existing OVS field that is currently
restricted from use by controllers, "dp_hash", and uses that for testing.
Because controllers cannot use it, this leaves future versions of OVS free
to drop the support for the experimenter OXM for this field without causing
backward compatibility problems.

Signed-off-by: Ben Pfaff <[email protected]>
Acked-by: Jarno Rajahalme <[email protected]>
  • Loading branch information
blp committed Oct 8, 2014
1 parent 0429d95 commit 508a933
Show file tree
Hide file tree
Showing 8 changed files with 339 additions and 83 deletions.
35 changes: 28 additions & 7 deletions build-aux/extract-ofp-fields
Original file line number Diff line number Diff line change
Expand Up @@ -48,12 +48,24 @@ PREREQS = {"none": "MFP_NONE",
"ND solicit": "MFP_ND_SOLICIT",
"ND advert": "MFP_ND_ADVERT"}

# Maps a name prefix to an oxm_class.
# Maps a name prefix into an (experimenter ID, class) pair, so:
#
# - Standard OXM classes are written as (0, <oxm_class>)
#
# - Experimenter OXM classes are written as (<oxm_vender>, 0xffff)
#
# If a name matches more than one prefix, the longest one is used.
OXM_CLASSES = {"NXM_OF_": 0x0000,
"NXM_NX_": 0x0001,
"OXM_OF_": 0x8000,
"OXM_OF_PKT_REG": 0x8001}
OXM_CLASSES = {"NXM_OF_": (0, 0x0000),
"NXM_NX_": (0, 0x0001),
"OXM_OF_": (0, 0x8000),
"OXM_OF_PKT_REG": (0, 0x8001),

# This is the experimenter OXM class for Nicira, which is the
# one that OVS would be using instead of NXM_OF_ and NXM_NX_
# if OVS didn't have those grandfathered in. It is currently
# used only to test support for experimenter OXM, since there
# are barely any real uses of experimenter OXM in the wild.
"NXOXM_ET_": (0x00002320, 0xffff)}
def oxm_name_to_class(name):
prefix = ''
class_ = None
Expand Down Expand Up @@ -118,12 +130,21 @@ def parse_oxm(s, prefix, n_bytes):
if not m:
fatal("%s: syntax error parsing %s" % (s, prefix))

name, code, of_version, ovs_version = m.groups()
name, oxm_type, of_version, ovs_version = m.groups()

class_ = oxm_name_to_class(name)
if class_ is None:
fatal("unknown OXM class for %s" % name)
header = ("NXM_HEADER(0x%04x,%s,0,%d)" % (class_, code, n_bytes))
oxm_vendor, oxm_class = class_

# Normally the oxm_length is the size of the field, but for experimenter
# OXMs oxm_length also includes the 4-byte experimenter ID.
oxm_length = n_bytes
if oxm_class == 0xffff:
oxm_length += 4

header = ("NXM_HEADER(0x%x,0x%x,%s,0,%d)"
% (oxm_vendor, oxm_class, oxm_type, oxm_length))

if of_version:
if of_version not in VERSION:
Expand Down
8 changes: 7 additions & 1 deletion lib/meta-flow.h
Original file line number Diff line number Diff line change
Expand Up @@ -263,13 +263,19 @@ enum OVS_PACKED_ENUM mf_field_id {
* Flow hash computed in the datapath. Internal use only, not programmable
* from controller.
*
* The OXM code point for this is an attempt to test OXM experimenter
* support, which is otherwise difficult to test due to the dearth of use
* out in the wild. Because controllers can't add flows that match on
* dp_hash, this doesn't commit OVS to supporting this OXM experimenter
* code point in the future.
*
* Type: be32.
* Maskable: bitwise.
* Formatting: hexadecimal.
* Prerequisites: none.
* Access: read-only.
* NXM: NXM_NX_DP_HASH(35) since v2.2.
* OXM: none.
* OXM: NXOXM_ET_DP_HASH(0) since OF1.5 and v2.4.
*/
MFF_DP_HASH,

Expand Down
Loading

0 comments on commit 508a933

Please sign in to comment.