--- /dev/null
+#! /usr/bin/python
+
+import sys
+import os.path
+import re
+
+line = ""
+
+# Maps from user-friendly version number to its protocol encoding.
+VERSION = {"1.0": 0x01,
+ "1.1": 0x02,
+ "1.2": 0x03,
+ "1.3": 0x04,
+ "1.4": 0x05,
+ "1.5": 0x06}
+
+TYPES = {"u8": 1,
+ "be16": 2,
+ "be32": 4,
+ "MAC": 6,
+ "be64": 8,
+ "IPv6": 16}
+
+FORMATTING = {"decimal": ("MFS_DECIMAL", 1, 8),
+ "hexadecimal": ("MFS_HEXADECIMAL", 1, 8),
+ "Ethernet": ("MFS_ETHERNET", 6, 6),
+ "IPv4": ("MFS_IPV4", 4, 4),
+ "IPv6": ("MFS_IPV6", 16,16),
+ "OpenFlow 1.0 port": ("MFS_OFP_PORT", 2, 2),
+ "OpenFlow 1.1+ port": ("MFS_OFP_PORT_OXM", 4, 4),
+ "frag": ("MFS_FRAG", 1, 1),
+ "tunnel flags": ("MFS_TNL_FLAGS", 2, 2),
+ "TCP flags": ("MFS_TCP_FLAGS", 2, 2)}
+
+PREREQS = {"none": "MFP_NONE",
+ "ARP": "MFP_ARP",
+ "VLAN VID": "MFP_VLAN_VID",
+ "IPv4": "MFP_IPV4",
+ "IPv6": "MFP_IPV6",
+ "IPv4/IPv6": "MFP_IP_ANY",
+ "MPLS": "MFP_MPLS",
+ "TCP": "MFP_TCP",
+ "UDP": "MFP_UDP",
+ "SCTP": "MFP_SCTP",
+ "ICMPv4": "MFP_ICMPV4",
+ "ICMPv6": "MFP_ICMPV6",
+ "ND": "MFP_ND",
+ "ND solicit": "MFP_ND_SOLICIT",
+ "ND advert": "MFP_ND_ADVERT"}
+
+# Maps a name prefix to an oxm_class.
+# 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}
+def oxm_name_to_class(name):
+ prefix = ''
+ class_ = None
+ for p, c in OXM_CLASSES.iteritems():
+ if name.startswith(p) and len(p) > len(prefix):
+ prefix = p
+ class_ = c
+ return class_
+
+def decode_version_range(range):
+ if range in VERSION:
+ return (VERSION[range], VERSION[range])
+ elif range.endswith('+'):
+ return (VERSION[range[:-1]], max(VERSION.values()))
+ else:
+ a, b = re.match(r'^([^-]+)-([^-]+)$', range).groups()
+ return (VERSION[a], VERSION[b])
+
+def get_line():
+ global line
+ global line_number
+ line = input_file.readline()
+ line_number += 1
+ if line == "":
+ fatal("unexpected end of input")
+
+n_errors = 0
+def error(msg):
+ global n_errors
+ sys.stderr.write("%s:%d: %s\n" % (file_name, line_number, msg))
+ n_errors += 1
+
+def fatal(msg):
+ error(msg)
+ sys.exit(1)
+
+def usage():
+ argv0 = os.path.basename(sys.argv[0])
+ print '''\
+%(argv0)s, for extracting OpenFlow field properties from meta-flow.h
+usage: %(argv0)s INPUT
+ where INPUT points to lib/meta-flow.h in the source directory.
+The output written to stdout is intended to be saved as lib/meta-flow.inc,
+which lib/meta-flow.c \"#include\"s.\
+''' % {"argv0": argv0}
+ sys.exit(0)
+
+def make_sizeof(s):
+ m = re.match(r'(.*) up to (.*)', s)
+ if m:
+ struct, member = m.groups()
+ return "offsetof(%s, %s)" % (struct, member)
+ else:
+ return "sizeof(%s)" % s
+
+def parse_oxm(s, prefix, n_bytes):
+ if s == 'none':
+ return None
+
+ m = re.match('([A-Z0-9_]+)\(([0-9]+)\) since(?: OF(1\.[0-9]+) and)? v([12]\.[0-9]+)$', s)
+ if not m:
+ fatal("%s: syntax error parsing %s" % (s, prefix))
+
+ name, code, 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, %d)" % (class_, code, n_bytes))
+
+ if of_version:
+ if of_version not in VERSION:
+ fatal("%s: unknown OpenFlow version %s" % (name, of_version))
+ of_version_nr = VERSION[of_version]
+ if of_version_nr < VERSION['1.2']:
+ fatal("%s: claimed version %s predates OXM" % (name, of_version))
+ else:
+ of_version_nr = 0
+
+ return (header, name, of_version_nr, ovs_version)
+
+def parse_field(mff, comment):
+ f = {'mff': mff}
+
+ # First line of comment is the field name.
+ m = re.match(r'"([^"]+)"(?:\s+\(aka "([^"]+)"\))?(?:\s+\(.*\))?\.', comment[0])
+ if not m:
+ fatal("%s lacks field name" % mff)
+ f['name'], f['extra_name'] = m.groups()
+
+ # Find the last blank line the comment. The field definitions
+ # start after that.
+ blank = None
+ for i in range(len(comment)):
+ if not comment[i]:
+ blank = i
+ if not blank:
+ fatal("%s: missing blank line in comment" % mff)
+
+ d = {}
+ for key in ("Type", "Maskable", "Formatting", "Prerequisites",
+ "Access", "Prefix lookup member",
+ "OXM", "NXM", "OF1.0", "OF1.1"):
+ d[key] = None
+ for fline in comment[blank + 1:]:
+ m = re.match(r'([^:]+):\s+(.*)\.$', fline)
+ if not m:
+ fatal("%s: syntax error parsing key-value pair as part of %s"
+ % (fline, mff))
+ key, value = m.groups()
+ if key not in d:
+ fatal("%s: unknown key" % key)
+ elif key == 'Code point':
+ d[key] += [value]
+ elif d[key] is not None:
+ fatal("%s: duplicate key" % key)
+ d[key] = value
+ for key, value in d.iteritems():
+ if not value and key not in ("OF1.0", "OF1.1",
+ "Prefix lookup member", "Notes"):
+ fatal("%s: missing %s" % (mff, key))
+
+ m = re.match(r'([a-zA-Z0-9]+)(?: \(low ([0-9]+) bits\))?$', d['Type'])
+ if not m:
+ fatal("%s: syntax error in type" % mff)
+ type_ = m.group(1)
+ if type_ not in TYPES:
+ fatal("%s: unknown type %s" % (mff, d['Type']))
+ f['n_bytes'] = TYPES[type_]
+ if m.group(2):
+ f['n_bits'] = int(m.group(2))
+ if f['n_bits'] > f['n_bytes'] * 8:
+ fatal("%s: more bits (%d) than field size (%d)"
+ % (mff, f['n_bits'], 8 * f['n_bytes']))
+ else:
+ f['n_bits'] = 8 * f['n_bytes']
+
+ if d['Maskable'] == 'no':
+ f['mask'] = 'MFM_NONE'
+ elif d['Maskable'] == 'bitwise':
+ f['mask'] = 'MFM_FULLY'
+ else:
+ fatal("%s: unknown maskable %s" % (mff, d['Maskable']))
+
+ fmt = FORMATTING.get(d['Formatting'])
+ if not fmt:
+ fatal("%s: unknown format %s" % (mff, d['Formatting']))
+ if f['n_bytes'] < fmt[1] or f['n_bytes'] > fmt[2]:
+ fatal("%s: %d-byte field can't be formatted as %s"
+ % (mff, f['n_bytes'], d['Formatting']))
+ f['string'] = fmt[0]
+
+ f['prereqs'] = PREREQS.get(d['Prerequisites'])
+ if not f['prereqs']:
+ fatal("%s: unknown prerequisites %s" % (mff, d['Prerequisites']))
+
+ if d['Access'] == 'read-only':
+ f['writable'] = False
+ elif d['Access'] == 'read/write':
+ f['writable'] = True
+ else:
+ fatal("%s: unknown access %s" % (mff, d['Access']))
+
+ f['OF1.0'] = d['OF1.0']
+ if not d['OF1.0'] in (None, 'exact match', 'CIDR mask'):
+ fatal("%s: unknown OF1.0 match type %s" % (mff, d['OF1.0']))
+
+ f['OF1.1'] = d['OF1.1']
+ if not d['OF1.1'] in (None, 'exact match', 'bitwise mask'):
+ fatal("%s: unknown OF1.1 match type %s" % (mff, d['OF1.1']))
+
+ f['OXM'] = parse_oxm(d['OXM'], 'OXM', f['n_bytes'])
+ f['NXM'] = parse_oxm(d['NXM'], 'NXM', f['n_bytes'])
+
+ f['prefix'] = d["Prefix lookup member"]
+
+ return f
+
+def protocols_to_c(protocols):
+ if protocols == set(['of10', 'of11', 'oxm']):
+ return 'OFPUTIL_P_ANY'
+ elif protocols == set(['of11', 'oxm']):
+ return 'OFPUTIL_P_NXM_OF11_UP'
+ elif protocols == set(['oxm']):
+ return 'OFPUTIL_P_NXM_OXM_ANY'
+ elif protocols == set([]):
+ return 'OFPUTIL_P_NONE'
+ else:
+ assert False
+
+def extract_ofp_fields():
+ global line
+
+ fields = []
+
+ while True:
+ get_line()
+ if re.match('enum.*mf_field_id', line):
+ break
+
+ while True:
+ get_line()
+ first_line_number = line_number
+ here = '%s:%d' % (file_name, line_number)
+ if (line.startswith('/*')
+ or line.startswith(' *')
+ or line.startswith('#')
+ or not line
+ or line.isspace()):
+ continue
+ elif re.match('}', line) or re.match('\s+MFF_N_IDS', line):
+ break
+
+ # Parse the comment preceding an MFF_ constant into 'comment',
+ # one line to an array element.
+ line = line.strip()
+ if not line.startswith('/*'):
+ fatal("unexpected syntax between fields")
+ line = line[1:]
+ comment = []
+ end = False
+ while not end:
+ line = line.strip()
+ if line.startswith('*/'):
+ get_line()
+ break
+ if not line.startswith('*'):
+ fatal("unexpected syntax within field")
+
+ line = line[1:]
+ if line.startswith(' '):
+ line = line[1:]
+ if line.startswith(' ') and comment:
+ continuation = True
+ line = line.lstrip()
+ else:
+ continuation = False
+
+ if line.endswith('*/'):
+ line = line[:-2].rstrip()
+ end = True
+ else:
+ end = False
+
+ if continuation:
+ comment[-1] += " " + line
+ else:
+ comment += [line]
+ get_line()
+
+ # Drop blank lines at each end of comment.
+ while comment and not comment[0]:
+ comment = comment[1:]
+ while comment and not comment[-1]:
+ comment = comment[:-1]
+
+ # Parse the MFF_ constant(s).
+ mffs = []
+ while True:
+ m = re.match('\s+(MFF_[A-Z0-9_]+),?\s?$', line)
+ if not m:
+ break
+ mffs += [m.group(1)]
+ get_line()
+ if not mffs:
+ fatal("unexpected syntax looking for MFF_ constants")
+
+ if len(mffs) > 1 or '<N>' in comment[0]:
+ for mff in mffs:
+ # Extract trailing integer.
+ m = re.match('.*[^0-9]([0-9]+)$', mff)
+ if not m:
+ fatal("%s lacks numeric suffix in register group" % mff)
+ n = m.group(1)
+
+ # Search-and-replace <N> within the comment,
+ # and drop lines that have <x> for x != n.
+ instance = []
+ for x in comment:
+ y = x.replace('<N>', n)
+ if re.search('<[0-9]+>', y):
+ if ('<%s>' % n) not in y:
+ continue
+ y = re.sub('<[0-9]+>', '', y)
+ instance += [y.strip()]
+ fields += [parse_field(mff, instance)]
+ else:
+ fields += [parse_field(mffs[0], comment)]
+ continue
+
+ input_file.close()
+
+ if n_errors:
+ sys.exit(1)
+
+ output = []
+ output += ["/* Generated automatically; do not modify! "
+ "-*- buffer-read-only: t -*- */"]
+ output += [""]
+
+ for f in fields:
+ output += ["{"]
+ output += [" %s," % f['mff']]
+ if f['extra_name']:
+ output += [" \"%s\", \"%s\"," % (f['name'], f['extra_name'])]
+ else:
+ output += [" \"%s\", NULL," % f['name']]
+ output += [" %d, %d," % (f['n_bytes'], f['n_bits'])]
+
+ if f['writable']:
+ rw = 'true'
+ else:
+ rw = 'false'
+ output += [" %s, %s, %s, %s,"
+ % (f['mask'], f['string'], f['prereqs'], rw)]
+
+ nxm = f['NXM']
+ oxm = f['OXM']
+ if not nxm:
+ nxm = oxm
+ elif not oxm:
+ oxm = nxm
+ if nxm:
+ output += [" %s, \"%s\"," % (nxm[0], nxm[1])]
+ output += [" %s, \"%s\", %s," % (oxm[0], oxm[1], oxm[2])]
+ else:
+ output += [" 0, NULL, 0, NULL, 0, /* no NXM or OXM */"]
+
+ of10 = f['OF1.0']
+ of11 = f['OF1.1']
+ if f['mff'] in ('MFF_DL_VLAN', 'MFF_DL_VLAN_PCP'):
+ # MFF_DL_VLAN and MFF_DL_VLAN_PCP don't exactly correspond to
+ # OF1.1, nor do they have NXM or OXM assignments, but their
+ # meanings can be expressed in every protocol, which is the goal of
+ # this member.
+ protocols = set(["of10", "of11", "oxm"])
+ else:
+ protocols = set([])
+ if of10:
+ protocols |= set(["of10"])
+ if of11:
+ protocols |= set(["of11"])
+ if nxm or oxm:
+ protocols |= set(["oxm"])
+
+ if f['mask'] == 'MFM_FULLY':
+ cidr_protocols = protocols.copy()
+ bitwise_protocols = protocols.copy()
+
+ if of10 == 'exact match':
+ bitwise_protocols -= set(['of10'])
+ cidr_protocols -= set(['of10'])
+ elif of10 == 'CIDR mask':
+ bitwise_protocols -= set(['of10'])
+ else:
+ assert of10 is None
+
+ if of11 == 'exact match':
+ bitwise_protocols -= set(['of11'])
+ cidr_protocols -= set(['of11'])
+ else:
+ assert of11 in (None, 'bitwise mask')
+ else:
+ assert f['mask'] == 'MFM_NONE'
+ cidr_protocols = set([])
+ bitwise_protocols = set([])
+
+ output += [" %s," % protocols_to_c(protocols)]
+ output += [" %s," % protocols_to_c(cidr_protocols)]
+ output += [" %s," % protocols_to_c(bitwise_protocols)]
+
+ if f['prefix']:
+ output += [" FLOW_U32OFS(%s)," % f['prefix']]
+ else:
+ output += [" -1, /* not usable for prefix lookup */"]
+
+ output += ["},"]
+
+ if n_errors:
+ sys.exit(1)
+
+ return output
+
+
+if __name__ == '__main__':
+ if '--help' in sys.argv:
+ usage()
+ elif len(sys.argv) != 2:
+ sys.stderr.write("exactly one non-option argument required; "
+ "use --help for help\n")
+ sys.exit(1)
+ else:
+ global file_name
+ global input_file
+ global line_number
+ file_name = sys.argv[1]
+ input_file = open(file_name)
+ line_number = 0
+
+ for oline in extract_ofp_fields():
+ print oline
+
#define NXM_MAKE_WILD_HEADER(HEADER) \
NXM_HEADER_W(NXM_VENDOR(HEADER), NXM_FIELD(HEADER), NXM_LENGTH(HEADER))
-/* ## ------------------------------- ## */
-/* ## OpenFlow 1.0-compatible fields. ## */
-/* ## ------------------------------- ## */
-
-/* Physical or virtual port on which the packet was received.
- *
- * Prereqs: None.
- *
- * Format: 16-bit integer in network byte order.
- *
- * Masking: Not maskable. */
-#define NXM_OF_IN_PORT NXM_HEADER (0x0000, 0, 2)
-
-/* Source or destination address in Ethernet header.
- *
- * Prereqs: None.
- *
- * Format: 48-bit Ethernet MAC address.
- *
- * Masking: Fully maskable, in versions 1.8 and later. Earlier versions only
- * supported the following masks for NXM_OF_ETH_DST_W: 00:00:00:00:00:00,
- * fe:ff:ff:ff:ff:ff, 01:00:00:00:00:00, ff:ff:ff:ff:ff:ff. */
-#define NXM_OF_ETH_DST NXM_HEADER (0x0000, 1, 6)
-#define NXM_OF_ETH_DST_W NXM_HEADER_W(0x0000, 1, 6)
-#define NXM_OF_ETH_SRC NXM_HEADER (0x0000, 2, 6)
-#define NXM_OF_ETH_SRC_W NXM_HEADER_W(0x0000, 2, 6)
-
-/* Packet's Ethernet type.
- *
- * For an Ethernet II packet this is taken from the Ethernet header. For an
- * 802.2 LLC+SNAP header with OUI 00-00-00 this is taken from the SNAP header.
- * A packet that has neither format has value 0x05ff
- * (OFP_DL_TYPE_NOT_ETH_TYPE).
- *
- * For a packet with an 802.1Q header, this is the type of the encapsulated
- * frame.
- *
- * Prereqs: None.
- *
- * Format: 16-bit integer in network byte order.
- *
- * Masking: Not maskable. */
-#define NXM_OF_ETH_TYPE NXM_HEADER (0x0000, 3, 2)
-
-/* 802.1Q TCI.
- *
- * For a packet with an 802.1Q header, this is the Tag Control Information
- * (TCI) field, with the CFI bit forced to 1. For a packet with no 802.1Q
- * header, this has value 0.
- *
- * Prereqs: None.
- *
- * Format: 16-bit integer in network byte order.
- *
- * Masking: Arbitrary masks.
- *
- * This field can be used in various ways:
- *
- * - If it is not constrained at all, the nx_match matches packets without
- * an 802.1Q header or with an 802.1Q header that has any TCI value.
- *
- * - Testing for an exact match with 0 matches only packets without an
- * 802.1Q header.
- *
- * - Testing for an exact match with a TCI value with CFI=1 matches packets
- * that have an 802.1Q header with a specified VID and PCP.
- *
- * - Testing for an exact match with a nonzero TCI value with CFI=0 does
- * not make sense. The switch may reject this combination.
- *
- * - Testing with a specific VID and CFI=1, with nxm_mask=0x1fff, matches
- * packets that have an 802.1Q header with that VID (and any PCP).
- *
- * - Testing with a specific PCP and CFI=1, with nxm_mask=0xf000, matches
- * packets that have an 802.1Q header with that PCP (and any VID).
- *
- * - Testing with nxm_value=0, nxm_mask=0x0fff matches packets with no 802.1Q
- * header or with an 802.1Q header with a VID of 0.
- *
- * - Testing with nxm_value=0, nxm_mask=0xe000 matches packets with no 802.1Q
- * header or with an 802.1Q header with a PCP of 0.
- *
- * - Testing with nxm_value=0, nxm_mask=0xefff matches packets with no 802.1Q
- * header or with an 802.1Q header with both VID and PCP of 0.
- */
-#define NXM_OF_VLAN_TCI NXM_HEADER (0x0000, 4, 2)
-#define NXM_OF_VLAN_TCI_W NXM_HEADER_W(0x0000, 4, 2)
-
-/* The "type of service" byte of the IP header, with the ECN bits forced to 0.
- *
- * Prereqs: NXM_OF_ETH_TYPE must be either 0x0800 or 0x86dd.
- *
- * Format: 8-bit integer with 2 least-significant bits forced to 0.
- *
- * Masking: Not maskable. */
-#define NXM_OF_IP_TOS NXM_HEADER (0x0000, 5, 1)
-
-/* The "protocol" byte in the IP header.
- *
- * Prereqs: NXM_OF_ETH_TYPE must be either 0x0800 or 0x86dd.
- *
- * Format: 8-bit integer.
- *
- * Masking: Not maskable. */
-#define NXM_OF_IP_PROTO NXM_HEADER (0x0000, 6, 1)
-
-/* The source or destination address in the IP header.
- *
- * Prereqs: NXM_OF_ETH_TYPE must match 0x0800 exactly.
- *
- * Format: 32-bit integer in network byte order.
- *
- * Masking: Fully maskable, in Open vSwitch 1.8 and later. In earlier
- * versions, only CIDR masks are allowed, that is, masks that consist of N
- * high-order bits set to 1 and the other 32-N bits set to 0. */
-#define NXM_OF_IP_SRC NXM_HEADER (0x0000, 7, 4)
-#define NXM_OF_IP_SRC_W NXM_HEADER_W(0x0000, 7, 4)
-#define NXM_OF_IP_DST NXM_HEADER (0x0000, 8, 4)
-#define NXM_OF_IP_DST_W NXM_HEADER_W(0x0000, 8, 4)
-
-/* The source or destination port in the TCP header.
- *
- * Prereqs:
- * NXM_OF_ETH_TYPE must be either 0x0800 or 0x86dd.
- * NXM_OF_IP_PROTO must match 6 exactly.
- *
- * Format: 16-bit integer in network byte order.
- *
- * Masking: Fully maskable, in Open vSwitch 1.6 and later. Not maskable, in
- * earlier versions. */
-#define NXM_OF_TCP_SRC NXM_HEADER (0x0000, 9, 2)
-#define NXM_OF_TCP_SRC_W NXM_HEADER_W(0x0000, 9, 2)
-#define NXM_OF_TCP_DST NXM_HEADER (0x0000, 10, 2)
-#define NXM_OF_TCP_DST_W NXM_HEADER_W(0x0000, 10, 2)
-
-/* The source or destination port in the UDP header.
- *
- * Prereqs:
- * NXM_OF_ETH_TYPE must match either 0x0800 or 0x86dd.
- * NXM_OF_IP_PROTO must match 17 exactly.
- *
- * Format: 16-bit integer in network byte order.
- *
- * Masking: Fully maskable, in Open vSwitch 1.6 and later. Not maskable, in
- * earlier versions. */
-#define NXM_OF_UDP_SRC NXM_HEADER (0x0000, 11, 2)
-#define NXM_OF_UDP_SRC_W NXM_HEADER_W(0x0000, 11, 2)
-#define NXM_OF_UDP_DST NXM_HEADER (0x0000, 12, 2)
-#define NXM_OF_UDP_DST_W NXM_HEADER_W(0x0000, 12, 2)
-
-/* The type or code in the ICMP header.
- *
- * Prereqs:
- * NXM_OF_ETH_TYPE must match 0x0800 exactly.
- * NXM_OF_IP_PROTO must match 1 exactly.
- *
- * Format: 8-bit integer.
- *
- * Masking: Not maskable. */
-#define NXM_OF_ICMP_TYPE NXM_HEADER (0x0000, 13, 1)
-#define NXM_OF_ICMP_CODE NXM_HEADER (0x0000, 14, 1)
-
-/* ARP opcode.
- *
- * For an Ethernet+IP ARP packet, the opcode in the ARP header. Always 0
- * otherwise. Only ARP opcodes between 1 and 255 should be specified for
- * matching.
- *
- * Prereqs: NXM_OF_ETH_TYPE must match either 0x0806 or 0x8035.
- *
- * Format: 16-bit integer in network byte order.
- *
- * Masking: Not maskable. */
-#define NXM_OF_ARP_OP NXM_HEADER (0x0000, 15, 2)
-
-/* For an Ethernet+IP ARP packet, the source or target protocol address
- * in the ARP header. Always 0 otherwise.
- *
- * Prereqs: NXM_OF_ETH_TYPE must match either 0x0806 or 0x8035.
- *
- * Format: 32-bit integer in network byte order.
- *
- * Masking: Fully maskable, in Open vSwitch 1.8 and later. In earlier
- * versions, only CIDR masks are allowed, that is, masks that consist of N
- * high-order bits set to 1 and the other 32-N bits set to 0. */
-#define NXM_OF_ARP_SPA NXM_HEADER (0x0000, 16, 4)
-#define NXM_OF_ARP_SPA_W NXM_HEADER_W(0x0000, 16, 4)
-#define NXM_OF_ARP_TPA NXM_HEADER (0x0000, 17, 4)
-#define NXM_OF_ARP_TPA_W NXM_HEADER_W(0x0000, 17, 4)
-
-/* ## ------------------------ ## */
-/* ## Nicira match extensions. ## */
-/* ## ------------------------ ## */
-
-/* Metadata registers.
- *
- * Registers initially have value 0. Actions allow register values to be
- * manipulated.
- *
- * Prereqs: None.
- *
- * Format: Array of 32-bit integer registers. Space is reserved for up to
- * NXM_NX_MAX_REGS registers, but switches may implement fewer.
- *
- * Masking: Arbitrary masks. */
+/* Number of registers allocated NXM field IDs. */
#define NXM_NX_MAX_REGS 16
-#define NXM_NX_REG(IDX) NXM_HEADER (0x0001, IDX, 4)
-#define NXM_NX_REG_W(IDX) NXM_HEADER_W(0x0001, IDX, 4)
-#define NXM_NX_REG_IDX(HEADER) NXM_FIELD(HEADER)
-#define NXM_IS_NX_REG(HEADER) (!((((HEADER) ^ NXM_NX_REG0)) & 0xffffe1ff))
-#define NXM_IS_NX_REG_W(HEADER) (!((((HEADER) ^ NXM_NX_REG0_W)) & 0xffffe1ff))
-#define NXM_NX_REG0 NXM_HEADER (0x0001, 0, 4)
-#define NXM_NX_REG0_W NXM_HEADER_W(0x0001, 0, 4)
-#define NXM_NX_REG1 NXM_HEADER (0x0001, 1, 4)
-#define NXM_NX_REG1_W NXM_HEADER_W(0x0001, 1, 4)
-#define NXM_NX_REG2 NXM_HEADER (0x0001, 2, 4)
-#define NXM_NX_REG2_W NXM_HEADER_W(0x0001, 2, 4)
-#define NXM_NX_REG3 NXM_HEADER (0x0001, 3, 4)
-#define NXM_NX_REG3_W NXM_HEADER_W(0x0001, 3, 4)
-#define NXM_NX_REG4 NXM_HEADER (0x0001, 4, 4)
-#define NXM_NX_REG4_W NXM_HEADER_W(0x0001, 4, 4)
-#define NXM_NX_REG5 NXM_HEADER (0x0001, 5, 4)
-#define NXM_NX_REG5_W NXM_HEADER_W(0x0001, 5, 4)
-#define NXM_NX_REG6 NXM_HEADER (0x0001, 6, 4)
-#define NXM_NX_REG6_W NXM_HEADER_W(0x0001, 6, 4)
-#define NXM_NX_REG7 NXM_HEADER (0x0001, 7, 4)
-#define NXM_NX_REG7_W NXM_HEADER_W(0x0001, 7, 4)
-
-/* Tunnel ID.
- *
- * For a packet received via a Geneve, GRE, VXLAN or LISP tunnel including a
- * key less than 64 bits, the key is stored in the low bits and the high bits
- * are zeroed. For other packets, the value is 0.
- *
- * All zero bits, for packets not received via a keyed tunnel.
- *
- * Prereqs: None.
- *
- * Format: 64-bit integer in network byte order.
- *
- * Masking: Arbitrary masks. */
-#define NXM_NX_TUN_ID NXM_HEADER (0x0001, 16, 8)
-#define NXM_NX_TUN_ID_W NXM_HEADER_W(0x0001, 16, 8)
-
-/* For an Ethernet+IP ARP packet, the source or target hardware address
- * in the ARP header. Always 0 otherwise.
- *
- * Prereqs: NXM_OF_ETH_TYPE must match either 0x0806 or 0x8035.
- *
- * Format: 48-bit Ethernet MAC address.
- *
- * Masking: Not maskable. */
-#define NXM_NX_ARP_SHA NXM_HEADER (0x0001, 17, 6)
-#define NXM_NX_ARP_THA NXM_HEADER (0x0001, 18, 6)
-
-/* The source or destination address in the IPv6 header.
- *
- * Prereqs: NXM_OF_ETH_TYPE must match 0x86dd exactly.
- *
- * Format: 128-bit IPv6 address.
- *
- * Masking: Fully maskable, in Open vSwitch 1.8 and later. In previous
- * versions, only CIDR masks are allowed, that is, masks that consist of N
- * high-order bits set to 1 and the other 128-N bits set to 0. */
-#define NXM_NX_IPV6_SRC NXM_HEADER (0x0001, 19, 16)
-#define NXM_NX_IPV6_SRC_W NXM_HEADER_W(0x0001, 19, 16)
-#define NXM_NX_IPV6_DST NXM_HEADER (0x0001, 20, 16)
-#define NXM_NX_IPV6_DST_W NXM_HEADER_W(0x0001, 20, 16)
-
-/* The type or code in the ICMPv6 header.
- *
- * Prereqs:
- * NXM_OF_ETH_TYPE must match 0x86dd exactly.
- * NXM_OF_IP_PROTO must match 58 exactly.
- *
- * Format: 8-bit integer.
- *
- * Masking: Not maskable. */
-#define NXM_NX_ICMPV6_TYPE NXM_HEADER (0x0001, 21, 1)
-#define NXM_NX_ICMPV6_CODE NXM_HEADER (0x0001, 22, 1)
-
-/* The target address in an IPv6 Neighbor Discovery message.
- *
- * Prereqs:
- * NXM_OF_ETH_TYPE must match 0x86dd exactly.
- * NXM_OF_IP_PROTO must match 58 exactly.
- * NXM_OF_ICMPV6_TYPE must be either 135 or 136.
- *
- * Format: 128-bit IPv6 address.
- *
- * Masking: Fully maskable, in Open vSwitch 1.8 and later. In previous
- * versions, only CIDR masks are allowed, that is, masks that consist of N
- * high-order bits set to 1 and the other 128-N bits set to 0. */
-#define NXM_NX_ND_TARGET NXM_HEADER (0x0001, 23, 16)
-#define NXM_NX_ND_TARGET_W NXM_HEADER_W (0x0001, 23, 16)
-
-/* The source link-layer address option in an IPv6 Neighbor Discovery
- * message.
- *
- * Prereqs:
- * NXM_OF_ETH_TYPE must match 0x86dd exactly.
- * NXM_OF_IP_PROTO must match 58 exactly.
- * NXM_OF_ICMPV6_TYPE must be exactly 135.
- *
- * Format: 48-bit Ethernet MAC address.
- *
- * Masking: Not maskable. */
-#define NXM_NX_ND_SLL NXM_HEADER (0x0001, 24, 6)
-
-/* The target link-layer address option in an IPv6 Neighbor Discovery
- * message.
- *
- * Prereqs:
- * NXM_OF_ETH_TYPE must match 0x86dd exactly.
- * NXM_OF_IP_PROTO must match 58 exactly.
- * NXM_OF_ICMPV6_TYPE must be exactly 136.
- *
- * Format: 48-bit Ethernet MAC address.
- *
- * Masking: Not maskable. */
-#define NXM_NX_ND_TLL NXM_HEADER (0x0001, 25, 6)
-
-/* IP fragment information.
- *
- * Prereqs:
- * NXM_OF_ETH_TYPE must be either 0x0800 or 0x86dd.
- *
- * Format: 8-bit value with one of the values 0, 1, or 3, as described below.
- *
- * Masking: Fully maskable.
- *
- * This field has three possible values:
- *
- * - A packet that is not an IP fragment has value 0.
- *
- * - A packet that is an IP fragment with offset 0 (the first fragment) has
- * bit 0 set and thus value 1.
- *
- * - A packet that is an IP fragment with nonzero offset has bits 0 and 1 set
- * and thus value 3.
- *
- * NX_IP_FRAG_ANY and NX_IP_FRAG_LATER are declared to symbolically represent
- * the meanings of bits 0 and 1.
- *
- * The switch may reject matches against values that can never appear.
- *
- * It is important to understand how this field interacts with the OpenFlow IP
- * fragment handling mode:
- *
- * - In OFPC_FRAG_DROP mode, the OpenFlow switch drops all IP fragments
- * before they reach the flow table, so every packet that is available for
- * matching will have value 0 in this field.
- *
- * - Open vSwitch does not implement OFPC_FRAG_REASM mode, but if it did then
- * IP fragments would be reassembled before they reached the flow table and
- * again every packet available for matching would always have value 0.
- *
- * - In OFPC_FRAG_NORMAL mode, all three values are possible, but OpenFlow
- * 1.0 says that fragments' transport ports are always 0, even for the
- * first fragment, so this does not provide much extra information.
- *
- * - In OFPC_FRAG_NX_MATCH mode, all three values are possible. For
- * fragments with offset 0, Open vSwitch makes L4 header information
- * available.
- */
-#define NXM_NX_IP_FRAG NXM_HEADER (0x0001, 26, 1)
-#define NXM_NX_IP_FRAG_W NXM_HEADER_W(0x0001, 26, 1)
/* Bits in the value of NXM_NX_IP_FRAG. */
#define NX_IP_FRAG_ANY (1 << 0) /* Is this a fragment? */
#define NX_IP_FRAG_LATER (1 << 1) /* Is this a fragment with nonzero offset? */
-/* The flow label in the IPv6 header.
- *
- * Prereqs: NXM_OF_ETH_TYPE must match 0x86dd exactly.
- *
- * Format: 20-bit IPv6 flow label in least-significant bits.
- *
- * Masking: Fully maskable. */
-#define NXM_NX_IPV6_LABEL NXM_HEADER (0x0001, 27, 4)
-#define NXM_NX_IPV6_LABEL_W NXM_HEADER_W(0x0001, 27, 4)
-
-/* The ECN of the IP header.
- *
- * Prereqs: NXM_OF_ETH_TYPE must be either 0x0800 or 0x86dd.
- *
- * Format: ECN in the low-order 2 bits.
- *
- * Masking: Not maskable. */
-#define NXM_NX_IP_ECN NXM_HEADER (0x0001, 28, 1)
-
-/* The time-to-live/hop limit of the IP header.
- *
- * Prereqs: NXM_OF_ETH_TYPE must be either 0x0800 or 0x86dd.
- *
- * Format: 8-bit integer.
- *
- * Masking: Not maskable. */
-#define NXM_NX_IP_TTL NXM_HEADER (0x0001, 29, 1)
-
/* Flow cookie.
*
* This may be used to gain the OpenFlow 1.1-like ability to restrict
#define NXM_NX_COOKIE NXM_HEADER (0x0001, 30, 8)
#define NXM_NX_COOKIE_W NXM_HEADER_W(0x0001, 30, 8)
-/* The source or destination address in the outer IP header of a tunneled
- * packet.
- *
- * For non-tunneled packets, the value is 0.
- *
- * Prereqs: None.
- *
- * Format: 32-bit integer in network byte order.
- *
- * Masking: Fully maskable. */
-#define NXM_NX_TUN_IPV4_SRC NXM_HEADER (0x0001, 31, 4)
-#define NXM_NX_TUN_IPV4_SRC_W NXM_HEADER_W(0x0001, 31, 4)
-#define NXM_NX_TUN_IPV4_DST NXM_HEADER (0x0001, 32, 4)
-#define NXM_NX_TUN_IPV4_DST_W NXM_HEADER_W(0x0001, 32, 4)
-
-/* Metadata marked onto the packet in a system-dependent manner.
- *
- * The packet mark may be used to carry contextual information
- * to other parts of the system outside of Open vSwitch. As a
- * result, the semantics depend on system in use.
- *
- * Prereqs: None.
- *
- * Format: 32-bit integer in network byte order.
- *
- * Masking: Fully maskable. */
-#define NXM_NX_PKT_MARK NXM_HEADER (0x0001, 33, 4)
-#define NXM_NX_PKT_MARK_W NXM_HEADER_W(0x0001, 33, 4)
-
-/* The flags in the TCP header.
-*
-* Prereqs:
-* NXM_OF_ETH_TYPE must be either 0x0800 or 0x86dd.
-* NXM_OF_IP_PROTO must match 6 exactly.
-*
-* Format: 16-bit integer with 4 most-significant bits forced to 0.
-*
-* Masking: Bits 0-11 fully maskable. */
-#define NXM_NX_TCP_FLAGS NXM_HEADER (0x0001, 34, 2)
-#define NXM_NX_TCP_FLAGS_W NXM_HEADER_W(0x0001, 34, 2)
-
-/* Metadata dp_hash.
- *
- * Internal use only, not programable from controller.
- *
- * The dp_hash is used to carry the flow hash computed in the
- * datapath.
- *
- * Prereqs: None.
- *
- * Format: 32-bit integer in network byte order.
- *
- * Masking: Fully maskable. */
-#define NXM_NX_DP_HASH NXM_HEADER (0x0001, 35, 4)
-#define NXM_NX_DP_HASH_W NXM_HEADER_W(0x0001, 35, 4)
-
-/* Metadata recirc_id.
- *
- * Internal use only, not programable from controller.
- *
- * The recirc_id used for recirculation. 0 is reserved
- * for initially received packet.
- *
- * Prereqs: None.
- *
- * Format: 32-bit integer in network byte order.
- *
- * Masking: not maskable. */
-#define NXM_NX_RECIRC_ID NXM_HEADER (0x0001, 36, 4)
/* ## --------------------- ## */
/* ## Requests and replies. ## */
OFPXMC12_EXPERIMENTER = 0xffff, /* Experimenter class */
};
-/* OXM Flow match field types for OpenFlow basic class. */
-enum oxm12_ofb_match_fields {
- OFPXMT12_OFB_IN_PORT, /* Switch input port. */
- OFPXMT12_OFB_IN_PHY_PORT, /* Switch physical input port. */
- OFPXMT12_OFB_METADATA, /* Metadata passed between tables. */
- OFPXMT12_OFB_ETH_DST, /* Ethernet destination address. */
- OFPXMT12_OFB_ETH_SRC, /* Ethernet source address. */
- OFPXMT12_OFB_ETH_TYPE, /* Ethernet frame type. */
- OFPXMT12_OFB_VLAN_VID, /* VLAN id. */
- OFPXMT12_OFB_VLAN_PCP, /* VLAN priority. */
- OFPXMT12_OFB_IP_DSCP, /* IP DSCP (6 bits in ToS field). */
- OFPXMT12_OFB_IP_ECN, /* IP ECN (2 bits in ToS field). */
- OFPXMT12_OFB_IP_PROTO, /* IP protocol. */
- OFPXMT12_OFB_IPV4_SRC, /* IPv4 source address. */
- OFPXMT12_OFB_IPV4_DST, /* IPv4 destination address. */
- OFPXMT12_OFB_TCP_SRC, /* TCP source port. */
- OFPXMT12_OFB_TCP_DST, /* TCP destination port. */
- OFPXMT12_OFB_UDP_SRC, /* UDP source port. */
- OFPXMT12_OFB_UDP_DST, /* UDP destination port. */
- OFPXMT12_OFB_SCTP_SRC, /* SCTP source port. */
- OFPXMT12_OFB_SCTP_DST, /* SCTP destination port. */
- OFPXMT12_OFB_ICMPV4_TYPE, /* ICMP type. */
- OFPXMT12_OFB_ICMPV4_CODE, /* ICMP code. */
- OFPXMT12_OFB_ARP_OP, /* ARP opcode. */
- OFPXMT12_OFB_ARP_SPA, /* ARP source IPv4 address. */
- OFPXMT12_OFB_ARP_TPA, /* ARP target IPv4 address. */
- OFPXMT12_OFB_ARP_SHA, /* ARP source hardware address. */
- OFPXMT12_OFB_ARP_THA, /* ARP target hardware address. */
- OFPXMT12_OFB_IPV6_SRC, /* IPv6 source address. */
- OFPXMT12_OFB_IPV6_DST, /* IPv6 destination address. */
- OFPXMT12_OFB_IPV6_FLABEL, /* IPv6 Flow Label */
- OFPXMT12_OFB_ICMPV6_TYPE, /* ICMPv6 type. */
- OFPXMT12_OFB_ICMPV6_CODE, /* ICMPv6 code. */
- OFPXMT12_OFB_IPV6_ND_TARGET, /* Target address for ND. */
- OFPXMT12_OFB_IPV6_ND_SLL, /* Source link-layer for ND. */
- OFPXMT12_OFB_IPV6_ND_TLL, /* Target link-layer for ND. */
- OFPXMT12_OFB_MPLS_LABEL, /* MPLS label. */
- OFPXMT12_OFB_MPLS_TC, /* MPLS TC. */
-
- /* Following added in OpenFlow 1.3 */
- OFPXMT13_OFB_MPLS_BOS, /* MPLS BoS bit. */
- OFPXMT13_OFB_PBB_ISID, /* PBB I-SID. */
- OFPXMT13_OFB_TUNNEL_ID, /* Logical Port Metadata */
- OFPXMT13_OFB_IPV6_EXTHDR, /* IPv6 Extension Header pseudo-field */
-
- /* Following added in OpenFlow 1.4. */
- OFPXMT14_OFB_PBB_UCA = 41, /* PBB UCA header field. */
-
- /* Following added in OpenFlow 1.5. */
- OFPXMT15_OFB_TCP_FLAGS = 42, /* TCP flags. */
- };
-
-/* OXM implementation makes use of NXM as they are the same format
- * with different field definitions
- */
-
-#define OXM_HEADER(FIELD, LENGTH) \
- NXM_HEADER(OFPXMC12_OPENFLOW_BASIC, FIELD, LENGTH)
-#define OXM_HEADER_W(FIELD, LENGTH) \
- NXM_HEADER_W(OFPXMC12_OPENFLOW_BASIC, FIELD, LENGTH)
-
#define IS_OXM_HEADER(header) (NXM_VENDOR(header) == OFPXMC12_OPENFLOW_BASIC)
-#define OXM_OF_IN_PORT OXM_HEADER (OFPXMT12_OFB_IN_PORT, 4)
-#define OXM_OF_IN_PHY_PORT OXM_HEADER (OFPXMT12_OFB_IN_PHY_PORT, 4)
-#define OXM_OF_METADATA OXM_HEADER (OFPXMT12_OFB_METADATA, 8)
-#define OXM_OF_ETH_DST OXM_HEADER (OFPXMT12_OFB_ETH_DST, 6)
-#define OXM_OF_ETH_DST_W OXM_HEADER_W (OFPXMT12_OFB_ETH_DST, 6)
-#define OXM_OF_ETH_SRC OXM_HEADER (OFPXMT12_OFB_ETH_SRC, 6)
-#define OXM_OF_ETH_SRC_W OXM_HEADER_W (OFPXMT12_OFB_ETH_SRC, 6)
-#define OXM_OF_ETH_TYPE OXM_HEADER (OFPXMT12_OFB_ETH_TYPE, 2)
-#define OXM_OF_VLAN_VID OXM_HEADER (OFPXMT12_OFB_VLAN_VID, 2)
-#define OXM_OF_VLAN_VID_W OXM_HEADER_W (OFPXMT12_OFB_VLAN_VID, 2)
-#define OXM_OF_VLAN_PCP OXM_HEADER (OFPXMT12_OFB_VLAN_PCP, 1)
-#define OXM_OF_IP_DSCP OXM_HEADER (OFPXMT12_OFB_IP_DSCP, 1)
-#define OXM_OF_IP_ECN OXM_HEADER (OFPXMT12_OFB_IP_ECN, 1)
-#define OXM_OF_IP_PROTO OXM_HEADER (OFPXMT12_OFB_IP_PROTO, 1)
-#define OXM_OF_IPV4_SRC OXM_HEADER (OFPXMT12_OFB_IPV4_SRC, 4)
-#define OXM_OF_IPV4_SRC_W OXM_HEADER_W (OFPXMT12_OFB_IPV4_SRC, 4)
-#define OXM_OF_IPV4_DST OXM_HEADER (OFPXMT12_OFB_IPV4_DST, 4)
-#define OXM_OF_IPV4_DST_W OXM_HEADER_W (OFPXMT12_OFB_IPV4_DST, 4)
-#define OXM_OF_TCP_SRC OXM_HEADER (OFPXMT12_OFB_TCP_SRC, 2)
-#define OXM_OF_TCP_DST OXM_HEADER (OFPXMT12_OFB_TCP_DST, 2)
-#define OXM_OF_UDP_SRC OXM_HEADER (OFPXMT12_OFB_UDP_SRC, 2)
-#define OXM_OF_UDP_DST OXM_HEADER (OFPXMT12_OFB_UDP_DST, 2)
-#define OXM_OF_SCTP_SRC OXM_HEADER (OFPXMT12_OFB_SCTP_SRC, 2)
-#define OXM_OF_SCTP_DST OXM_HEADER (OFPXMT12_OFB_SCTP_DST, 2)
-#define OXM_OF_ICMPV4_TYPE OXM_HEADER (OFPXMT12_OFB_ICMPV4_TYPE, 1)
-#define OXM_OF_ICMPV4_CODE OXM_HEADER (OFPXMT12_OFB_ICMPV4_CODE, 1)
-#define OXM_OF_ARP_OP OXM_HEADER (OFPXMT12_OFB_ARP_OP, 2)
-#define OXM_OF_ARP_SPA OXM_HEADER (OFPXMT12_OFB_ARP_SPA, 4)
-#define OXM_OF_ARP_SPA_W OXM_HEADER_W (OFPXMT12_OFB_ARP_SPA, 4)
-#define OXM_OF_ARP_TPA OXM_HEADER (OFPXMT12_OFB_ARP_TPA, 4)
-#define OXM_OF_ARP_TPA_W OXM_HEADER_W (OFPXMT12_OFB_ARP_TPA, 4)
-#define OXM_OF_ARP_SHA OXM_HEADER (OFPXMT12_OFB_ARP_SHA, 6)
-#define OXM_OF_ARP_SHA_W OXM_HEADER_W (OFPXMT12_OFB_ARP_SHA, 6)
-#define OXM_OF_ARP_THA OXM_HEADER (OFPXMT12_OFB_ARP_THA, 6)
-#define OXM_OF_ARP_THA_W OXM_HEADER_W (OFPXMT12_OFB_ARP_THA, 6)
-#define OXM_OF_IPV6_SRC OXM_HEADER (OFPXMT12_OFB_IPV6_SRC, 16)
-#define OXM_OF_IPV6_SRC_W OXM_HEADER_W (OFPXMT12_OFB_IPV6_SRC, 16)
-#define OXM_OF_IPV6_DST OXM_HEADER (OFPXMT12_OFB_IPV6_DST, 16)
-#define OXM_OF_IPV6_DST_W OXM_HEADER_W (OFPXMT12_OFB_IPV6_DST, 16)
-#define OXM_OF_IPV6_FLABEL OXM_HEADER (OFPXMT12_OFB_IPV6_FLABEL, 4)
-#define OXM_OF_IPV6_FLABEL_W OXM_HEADER_W (OFPXMT12_OFB_IPV6_FLABEL, 4)
-#define OXM_OF_ICMPV6_TYPE OXM_HEADER (OFPXMT12_OFB_ICMPV6_TYPE, 1)
-#define OXM_OF_ICMPV6_CODE OXM_HEADER (OFPXMT12_OFB_ICMPV6_CODE, 1)
-#define OXM_OF_IPV6_ND_TARGET OXM_HEADER (OFPXMT12_OFB_IPV6_ND_TARGET, 16)
-#define OXM_OF_IPV6_ND_SLL OXM_HEADER (OFPXMT12_OFB_IPV6_ND_SLL, 6)
-#define OXM_OF_IPV6_ND_TLL OXM_HEADER (OFPXMT12_OFB_IPV6_ND_TLL, 6)
-#define OXM_OF_MPLS_LABEL OXM_HEADER (OFPXMT12_OFB_MPLS_LABEL, 4)
-#define OXM_OF_MPLS_TC OXM_HEADER (OFPXMT12_OFB_MPLS_TC, 1)
-#define OXM_OF_MPLS_BOS OXM_HEADER (OFPXMT13_OFB_MPLS_BOS, 1)
-#define OXM_OF_PBB_ISID OXM_HEADER (OFPXMT12_OFB_PBB_ISID, 3)
-#define OXM_OF_PBB_ISID_W OXM_HEADER_W (OFPXMT12_OFB_PBB_ISID, 3)
-#define OXM_OF_TUNNEL_ID OXM_HEADER (OFPXMT13_OFB_TUNNEL_ID, 8)
-#define OXM_OF_TUNNEL_ID_W OXM_HEADER_W (OFPXMT13_OFB_TUNNEL_ID, 8)
-#define OXM_OF_IPV6_EXTHDR OXM_HEADER (OFPXMT13_OFB_IPV6_EXTHDR, 2)
-#define OXM_OF_IPV6_EXTHDR_W OXM_HEADER_W (OFPXMT13_OFB_IPV6_EXTHDR, 2)
-#define OXM_OF_PBB_UCA OXM_HEADER (OFPXMT14_OFB_PBB_UCA, 1)
-#define OXM_OF_TCP_FLAGS OXM_HEADER (OFPXMT15_OFB_TCP_FLAGS, 2)
-#define OXM_OF_TCP_FLAGS_W OXM_HEADER_W (OFPXMT15_OFB_TCP_FLAGS, 2)
-
-#define OXM_OF_PKT_REG(N) (NXM_HEADER (OFPXMC15_PACKET_REGS, N, 8))
-#define OXM_OF_PKT_REG_W(N) (NXM_HEADER_W(OFPXMC15_PACKET_REGS, N, 8))
-
/* The VLAN id is 12-bits, so we can use the entire 16 bits to indicate
* special conditions.
*/
> lib/dirs.c.tmp && \
mv lib/dirs.c.tmp lib/dirs.c
+lib/meta-flow.inc: $(srcdir)/build-aux/extract-ofp-fields lib/meta-flow.h
+ $(AM_V_GEN)$(run_python) $^ > $@.tmp && mv $@.tmp $@
+lib/meta-flow.lo: lib/meta-flow.inc
+CLEANFILES += lib/meta-flow.inc
+EXTRA_DIST += build-aux/extract-ofp-fields
+
lib/ofp-actions.inc1: $(srcdir)/build-aux/extract-ofp-actions lib/ofp-actions.c
$(AM_V_GEN)$(run_python) $^ --prototypes > $@.tmp && mv $@.tmp $@
lib/ofp-actions.inc2: $(srcdir)/build-aux/extract-ofp-actions lib/ofp-actions.c
$(AM_V_GEN)$(run_python) $^ --definitions > $@.tmp && mv $@.tmp $@
lib/ofp-actions.lo: lib/ofp-actions.inc1 lib/ofp-actions.inc2
CLEANFILES += lib/ofp-actions.inc1 lib/ofp-actions.inc2
-EXTRA_DIST += build-aux/extract-ofp-actions lib/ofp-errors.inc
+EXTRA_DIST += build-aux/extract-ofp-actions
$(srcdir)/lib/ofp-errors.inc: \
lib/ofp-errors.h include/openflow/openflow-common.h \
extern const struct mf_field mf_fields[MFF_N_IDS]; /* Silence a warning. */
const struct mf_field mf_fields[MFF_N_IDS] = {
- /* ## -------- ## */
- /* ## metadata ## */
- /* ## -------- ## */
-
- {
- MFF_DP_HASH, "dp_hash", NULL,
- MF_FIELD_SIZES(be32),
- MFM_FULLY,
- MFS_HEXADECIMAL,
- MFP_NONE,
- false,
- NXM_NX_DP_HASH, "NXM_NX_DP_HASH",
- NXM_NX_DP_HASH, "NXM_NX_DP_HASH", 0,
- OFPUTIL_P_NXM_OXM_ANY,
- OFPUTIL_P_NXM_OXM_ANY,
- -1,
- }, {
- MFF_RECIRC_ID, "recirc_id", NULL,
- MF_FIELD_SIZES(be32),
- MFM_NONE,
- MFS_DECIMAL,
- MFP_NONE,
- false,
- NXM_NX_RECIRC_ID, "NXM_NX_RECIRC_ID",
- NXM_NX_RECIRC_ID, "NXM_NX_RECIRC_ID", 0,
- OFPUTIL_P_NXM_OXM_ANY,
- OFPUTIL_P_NXM_OXM_ANY,
- -1,
- }, {
- MFF_TUN_ID, "tun_id", "tunnel_id",
- MF_FIELD_SIZES(be64),
- MFM_FULLY,
- MFS_HEXADECIMAL,
- MFP_NONE,
- true,
- NXM_NX_TUN_ID, "NXM_NX_TUN_ID",
- OXM_OF_TUNNEL_ID, "OXM_OF_TUNNEL_ID", OFP13_VERSION,
- OFPUTIL_P_NXM_OXM_ANY,
- OFPUTIL_P_NXM_OXM_ANY,
- FLOW_U32OFS(tunnel.tun_id),
- }, {
- MFF_TUN_SRC, "tun_src", NULL,
- MF_FIELD_SIZES(be32),
- MFM_FULLY,
- MFS_IPV4,
- MFP_NONE,
- true,
- NXM_NX_TUN_IPV4_SRC, "NXM_NX_TUN_IPV4_SRC",
- NXM_NX_TUN_IPV4_SRC, "NXM_NX_TUN_IPV4_SRC", 0,
- OFPUTIL_P_NXM_OXM_ANY,
- OFPUTIL_P_NXM_OXM_ANY,
- FLOW_U32OFS(tunnel.ip_src),
- }, {
- MFF_TUN_DST, "tun_dst", NULL,
- MF_FIELD_SIZES(be32),
- MFM_FULLY,
- MFS_IPV4,
- MFP_NONE,
- true,
- NXM_NX_TUN_IPV4_DST, "NXM_NX_TUN_IPV4_DST",
- NXM_NX_TUN_IPV4_DST, "NXM_NX_TUN_IPV4_DST", 0,
- OFPUTIL_P_NXM_OXM_ANY,
- OFPUTIL_P_NXM_OXM_ANY,
- FLOW_U32OFS(tunnel.ip_dst),
- }, {
- MFF_TUN_FLAGS, "tun_flags", NULL,
- MF_FIELD_SIZES(be16),
- MFM_NONE,
- MFS_TNL_FLAGS,
- MFP_NONE,
- false,
- 0, NULL,
- 0, NULL, 0,
- OFPUTIL_P_NONE,
- OFPUTIL_P_NONE,
- -1,
- }, {
- MFF_TUN_TTL, "tun_ttl", NULL,
- MF_FIELD_SIZES(u8),
- MFM_NONE,
- MFS_DECIMAL,
- MFP_NONE,
- false,
- 0, NULL,
- 0, NULL, 0,
- OFPUTIL_P_NONE,
- OFPUTIL_P_NONE,
- -1,
- }, {
- MFF_TUN_TOS, "tun_tos", NULL,
- MF_FIELD_SIZES(u8),
- MFM_NONE,
- MFS_DECIMAL,
- MFP_NONE,
- false,
- 0, NULL,
- 0, NULL, 0,
- OFPUTIL_P_NONE,
- OFPUTIL_P_NONE,
- -1,
- }, {
- MFF_METADATA, "metadata", NULL,
- MF_FIELD_SIZES(be64),
- MFM_FULLY,
- MFS_HEXADECIMAL,
- MFP_NONE,
- true,
- OXM_OF_METADATA, "OXM_OF_METADATA",
- OXM_OF_METADATA, "OXM_OF_METADATA", OFP12_VERSION,
- OFPUTIL_P_NXM_OF11_UP,
- OFPUTIL_P_NXM_OF11_UP,
- -1,
- }, {
- MFF_IN_PORT, "in_port", NULL,
- MF_FIELD_SIZES(be16),
- MFM_NONE,
- MFS_OFP_PORT,
- MFP_NONE,
- true,
- NXM_OF_IN_PORT, "NXM_OF_IN_PORT",
- NXM_OF_IN_PORT, "NXM_OF_IN_PORT", 0,
- OFPUTIL_P_ANY, /* OF11+ via mapping to 32 bits. */
- OFPUTIL_P_NONE,
- -1,
- }, {
- MFF_IN_PORT_OXM, "in_port_oxm", NULL,
- MF_FIELD_SIZES(be32),
- MFM_NONE,
- MFS_OFP_PORT_OXM,
- MFP_NONE,
- true,
- OXM_OF_IN_PORT, "OXM_OF_IN_PORT",
- OXM_OF_IN_PORT, "OXM_OF_IN_PORT", OFP12_VERSION,
- OFPUTIL_P_OF11_UP,
- OFPUTIL_P_NONE,
- -1,
- }, {
- MFF_SKB_PRIORITY, "skb_priority", NULL,
- MF_FIELD_SIZES(be32),
- MFM_NONE,
- MFS_HEXADECIMAL,
- MFP_NONE,
- false,
- 0, NULL,
- 0, NULL, 0,
- OFPUTIL_P_NONE,
- OFPUTIL_P_NONE,
- -1,
- }, {
- MFF_PKT_MARK, "pkt_mark", NULL,
- MF_FIELD_SIZES(be32),
- MFM_FULLY,
- MFS_HEXADECIMAL,
- MFP_NONE,
- true,
- NXM_NX_PKT_MARK, "NXM_NX_PKT_MARK",
- NXM_NX_PKT_MARK, "NXM_NX_PKT_MARK", 0,
- OFPUTIL_P_NXM_OXM_ANY,
- OFPUTIL_P_NXM_OXM_ANY,
- -1,
- },
-
-#define REGISTER(IDX) \
- { \
- MFF_REG##IDX, "reg" #IDX, NULL, \
- MF_FIELD_SIZES(be32), \
- MFM_FULLY, \
- MFS_HEXADECIMAL, \
- MFP_NONE, \
- true, \
- NXM_NX_REG(IDX), "NXM_NX_REG" #IDX, \
- NXM_NX_REG(IDX), "NXM_NX_REG" #IDX, 0, \
- OFPUTIL_P_NXM_OXM_ANY, \
- OFPUTIL_P_NXM_OXM_ANY, \
- -1, \
- }
-#if FLOW_N_REGS == 8
- REGISTER(0),
- REGISTER(1),
- REGISTER(2),
- REGISTER(3),
- REGISTER(4),
- REGISTER(5),
- REGISTER(6),
- REGISTER(7),
-#else
-#error "Need to update mf_fields[] to match FLOW_N_REGS"
-#endif
-
-#define XREGISTER(IDX) \
- { \
- MFF_XREG##IDX, "xreg" #IDX, NULL, \
- MF_FIELD_SIZES(be64), \
- MFM_FULLY, \
- MFS_HEXADECIMAL, \
- MFP_NONE, \
- true, \
- OXM_OF_PKT_REG(IDX), "OXM_OF_PKT_REG" #IDX, \
- OXM_OF_PKT_REG(IDX), "OXM_OF_PKT_REG" #IDX, OFP15_VERSION, \
- OFPUTIL_P_NXM_OXM_ANY, \
- OFPUTIL_P_NXM_OXM_ANY, \
- -1, \
- }
-#if FLOW_N_XREGS == 4
- XREGISTER(0),
- XREGISTER(1),
- XREGISTER(2),
- XREGISTER(3),
-#else
-#error "Need to update mf_fields[] to match FLOW_N_XREGS"
-#endif
-
- /* ## -- ## */
- /* ## L2 ## */
- /* ## -- ## */
-
- {
- MFF_ETH_SRC, "eth_src", "dl_src",
- MF_FIELD_SIZES(mac),
- MFM_FULLY,
- MFS_ETHERNET,
- MFP_NONE,
- true,
- NXM_OF_ETH_SRC, "NXM_OF_ETH_SRC",
- OXM_OF_ETH_SRC, "OXM_OF_ETH_SRC", OFP12_VERSION,
- OFPUTIL_P_ANY,
- OFPUTIL_P_NXM_OF11_UP, /* Bitwise masking only with NXM and OF11+! */
- -1,
- }, {
- MFF_ETH_DST, "eth_dst", "dl_dst",
- MF_FIELD_SIZES(mac),
- MFM_FULLY,
- MFS_ETHERNET,
- MFP_NONE,
- true,
- NXM_OF_ETH_DST, "NXM_OF_ETH_DST",
- OXM_OF_ETH_DST, "OXM_OF_ETH_DST", OFP12_VERSION,
- OFPUTIL_P_ANY,
- OFPUTIL_P_NXM_OF11_UP, /* Bitwise masking only with NXM and OF11+! */
- -1,
- }, {
- MFF_ETH_TYPE, "eth_type", "dl_type",
- MF_FIELD_SIZES(be16),
- MFM_NONE,
- MFS_HEXADECIMAL,
- MFP_NONE,
- false,
- NXM_OF_ETH_TYPE, "NXM_OF_ETH_TYPE",
- OXM_OF_ETH_TYPE, "OXM_OF_ETH_TYPE", OFP12_VERSION,
- OFPUTIL_P_ANY,
- OFPUTIL_P_NONE,
- -1,
- },
-
- {
- MFF_VLAN_TCI, "vlan_tci", NULL,
- MF_FIELD_SIZES(be16),
- MFM_FULLY,
- MFS_HEXADECIMAL,
- MFP_NONE,
- true,
- NXM_OF_VLAN_TCI, "NXM_OF_VLAN_TCI",
- NXM_OF_VLAN_TCI, "NXM_OF_VLAN_TCI", 0,
- OFPUTIL_P_ANY,
- OFPUTIL_P_NXM_OXM_ANY,
- -1,
- }, {
- MFF_DL_VLAN, "dl_vlan", NULL,
- sizeof(ovs_be16), 12,
- MFM_NONE,
- MFS_DECIMAL,
- MFP_NONE,
- true,
- 0, NULL,
- 0, NULL, 0,
- OFPUTIL_P_ANY,
- OFPUTIL_P_NXM_OXM_ANY,
- -1,
- }, {
- MFF_VLAN_VID, "vlan_vid", NULL,
- sizeof(ovs_be16), 12,
- MFM_FULLY,
- MFS_DECIMAL,
- MFP_NONE,
- true,
- OXM_OF_VLAN_VID, "OXM_OF_VLAN_VID",
- OXM_OF_VLAN_VID, "OXM_OF_VLAN_VID", OFP12_VERSION,
- OFPUTIL_P_ANY,
- OFPUTIL_P_NXM_OXM_ANY,
- -1,
- }, {
- MFF_DL_VLAN_PCP, "dl_vlan_pcp", NULL,
- 1, 3,
- MFM_NONE,
- MFS_DECIMAL,
- MFP_NONE,
- true,
- 0, NULL,
- 0, NULL, 0,
- OFPUTIL_P_ANY, /* Will be mapped to NXM and OXM. */
- OFPUTIL_P_NONE,
- -1,
- }, {
- MFF_VLAN_PCP, "vlan_pcp", NULL,
- 1, 3,
- MFM_NONE,
- MFS_DECIMAL,
- MFP_VLAN_VID,
- true,
- OXM_OF_VLAN_PCP, "OXM_OF_VLAN_PCP",
- OXM_OF_VLAN_PCP, "OXM_OF_VLAN_PCP", OFP12_VERSION,
- OFPUTIL_P_ANY, /* Will be mapped to OF10 and NXM. */
- OFPUTIL_P_NONE,
- -1,
- },
-
- /* ## ---- ## */
- /* ## L2.5 ## */
- /* ## ---- ## */
- {
- MFF_MPLS_LABEL, "mpls_label", NULL,
- 4, 20,
- MFM_NONE,
- MFS_DECIMAL,
- MFP_MPLS,
- true,
- OXM_OF_MPLS_LABEL, "OXM_OF_MPLS_LABEL",
- OXM_OF_MPLS_LABEL, "OXM_OF_MPLS_LABEL", OFP12_VERSION,
- OFPUTIL_P_NXM_OF11_UP,
- OFPUTIL_P_NONE,
- -1,
- }, {
- MFF_MPLS_TC, "mpls_tc", NULL,
- 1, 3,
- MFM_NONE,
- MFS_DECIMAL,
- MFP_MPLS,
- true,
- OXM_OF_MPLS_TC, "OXM_OF_MPLS_TC",
- OXM_OF_MPLS_TC, "OXM_OF_MPLS_TC", OFP12_VERSION,
- OFPUTIL_P_NXM_OF11_UP,
- OFPUTIL_P_NONE,
- -1,
- }, {
- MFF_MPLS_BOS, "mpls_bos", NULL,
- 1, 1,
- MFM_NONE,
- MFS_DECIMAL,
- MFP_MPLS,
- false,
- OXM_OF_MPLS_BOS, "OXM_OF_MPLS_BOS",
- OXM_OF_MPLS_BOS, "OXM_OF_MPLS_BOS", OFP13_VERSION,
- OFPUTIL_P_NXM_OXM_ANY,
- OFPUTIL_P_NONE,
- -1,
- },
-
- /* ## -- ## */
- /* ## L3 ## */
- /* ## -- ## */
-
- {
- MFF_IPV4_SRC, "ip_src", "nw_src",
- MF_FIELD_SIZES(be32),
- MFM_FULLY,
- MFS_IPV4,
- MFP_IPV4,
- true,
- NXM_OF_IP_SRC, "NXM_OF_IP_SRC",
- OXM_OF_IPV4_SRC, "OXM_OF_IPV4_SRC", OFP12_VERSION,
- OFPUTIL_P_ANY,
- OFPUTIL_P_NXM_OF11_UP,
- FLOW_U32OFS(nw_src),
- }, {
- MFF_IPV4_DST, "ip_dst", "nw_dst",
- MF_FIELD_SIZES(be32),
- MFM_FULLY,
- MFS_IPV4,
- MFP_IPV4,
- true,
- NXM_OF_IP_DST, "NXM_OF_IP_DST",
- OXM_OF_IPV4_DST, "OXM_OF_IPV4_DST", OFP12_VERSION,
- OFPUTIL_P_ANY,
- OFPUTIL_P_NXM_OF11_UP,
- FLOW_U32OFS(nw_dst),
- },
-
- {
- MFF_IPV6_SRC, "ipv6_src", NULL,
- MF_FIELD_SIZES(ipv6),
- MFM_FULLY,
- MFS_IPV6,
- MFP_IPV6,
- true,
- NXM_NX_IPV6_SRC, "NXM_NX_IPV6_SRC",
- OXM_OF_IPV6_SRC, "OXM_OF_IPV6_SRC", OFP12_VERSION,
- OFPUTIL_P_NXM_OXM_ANY,
- OFPUTIL_P_NXM_OXM_ANY,
- FLOW_U32OFS(ipv6_src),
- }, {
- MFF_IPV6_DST, "ipv6_dst", NULL,
- MF_FIELD_SIZES(ipv6),
- MFM_FULLY,
- MFS_IPV6,
- MFP_IPV6,
- true,
- NXM_NX_IPV6_DST, "NXM_NX_IPV6_DST",
- OXM_OF_IPV6_DST, "OXM_OF_IPV6_DST", OFP12_VERSION,
- OFPUTIL_P_NXM_OXM_ANY,
- OFPUTIL_P_NXM_OXM_ANY,
- FLOW_U32OFS(ipv6_dst),
- },
- {
- MFF_IPV6_LABEL, "ipv6_label", NULL,
- 4, 20,
- MFM_FULLY,
- MFS_HEXADECIMAL,
- MFP_IPV6,
- false,
- NXM_NX_IPV6_LABEL, "NXM_NX_IPV6_LABEL",
- OXM_OF_IPV6_FLABEL, "OXM_OF_IPV6_FLABEL", OFP12_VERSION,
- OFPUTIL_P_NXM_OXM_ANY,
- OFPUTIL_P_NXM_OXM_ANY,
- -1,
- },
-
- {
- MFF_IP_PROTO, "nw_proto", "ip_proto",
- MF_FIELD_SIZES(u8),
- MFM_NONE,
- MFS_DECIMAL,
- MFP_IP_ANY,
- false,
- NXM_OF_IP_PROTO, "NXM_OF_IP_PROTO",
- OXM_OF_IP_PROTO, "OXM_OF_IP_PROTO", OFP12_VERSION,
- OFPUTIL_P_ANY,
- OFPUTIL_P_NONE,
- -1,
- }, {
- MFF_IP_DSCP, "nw_tos", NULL,
- MF_FIELD_SIZES(u8),
- MFM_NONE,
- MFS_DECIMAL,
- MFP_IP_ANY,
- true,
- NXM_OF_IP_TOS, "NXM_OF_IP_TOS",
- NXM_OF_IP_TOS, "NXM_OF_IP_TOS", 0,
- OFPUTIL_P_ANY, /* Will be shifted for OXM. */
- OFPUTIL_P_NONE,
- -1,
- }, {
- MFF_IP_DSCP_SHIFTED, "ip_dscp", NULL,
- 1, 6,
- MFM_NONE,
- MFS_DECIMAL,
- MFP_IP_ANY,
- true,
- OXM_OF_IP_DSCP, "OXM_OF_IP_DSCP",
- OXM_OF_IP_DSCP, "OXM_OF_IP_DSCP", OFP12_VERSION,
- OFPUTIL_P_ANY, /* Will be shifted for non-OXM. */
- OFPUTIL_P_NONE,
- -1,
- }, {
- MFF_IP_ECN, "nw_ecn", "ip_ecn",
- 1, 2,
- MFM_NONE,
- MFS_DECIMAL,
- MFP_IP_ANY,
- true,
- NXM_NX_IP_ECN, "NXM_NX_IP_ECN",
- OXM_OF_IP_ECN, "OXM_OF_IP_ECN", OFP12_VERSION,
- OFPUTIL_P_NXM_OXM_ANY,
- OFPUTIL_P_NONE,
- -1,
- }, {
- MFF_IP_TTL, "nw_ttl", NULL,
- MF_FIELD_SIZES(u8),
- MFM_NONE,
- MFS_DECIMAL,
- MFP_IP_ANY,
- true,
- NXM_NX_IP_TTL, "NXM_NX_IP_TTL",
- NXM_NX_IP_TTL, "NXM_NX_IP_TTL", 0,
- OFPUTIL_P_NXM_OXM_ANY,
- OFPUTIL_P_NONE,
- -1,
- }, {
- MFF_IP_FRAG, "ip_frag", NULL,
- 1, 2,
- MFM_FULLY,
- MFS_FRAG,
- MFP_IP_ANY,
- false,
- NXM_NX_IP_FRAG, "NXM_NX_IP_FRAG",
- NXM_NX_IP_FRAG, "NXM_NX_IP_FRAG", 0,
- OFPUTIL_P_NXM_OXM_ANY,
- OFPUTIL_P_NXM_OXM_ANY,
- -1,
- },
-
- {
- MFF_ARP_OP, "arp_op", NULL,
- MF_FIELD_SIZES(be16),
- MFM_NONE,
- MFS_DECIMAL,
- MFP_ARP,
- true,
- NXM_OF_ARP_OP, "NXM_OF_ARP_OP",
- OXM_OF_ARP_OP, "OXM_OF_ARP_OP", OFP12_VERSION,
- OFPUTIL_P_ANY,
- OFPUTIL_P_NONE,
- -1,
- }, {
- MFF_ARP_SPA, "arp_spa", NULL,
- MF_FIELD_SIZES(be32),
- MFM_FULLY,
- MFS_IPV4,
- MFP_ARP,
- true,
- NXM_OF_ARP_SPA, "NXM_OF_ARP_SPA",
- OXM_OF_ARP_SPA, "OXM_OF_ARP_SPA", OFP12_VERSION,
- OFPUTIL_P_ANY,
- OFPUTIL_P_NXM_OF11_UP,
- -1,
- }, {
- MFF_ARP_TPA, "arp_tpa", NULL,
- MF_FIELD_SIZES(be32),
- MFM_FULLY,
- MFS_IPV4,
- MFP_ARP,
- true,
- NXM_OF_ARP_TPA, "NXM_OF_ARP_TPA",
- OXM_OF_ARP_TPA, "OXM_OF_ARP_TPA", OFP12_VERSION,
- OFPUTIL_P_ANY,
- OFPUTIL_P_NXM_OF11_UP,
- -1,
- }, {
- MFF_ARP_SHA, "arp_sha", NULL,
- MF_FIELD_SIZES(mac),
- MFM_FULLY,
- MFS_ETHERNET,
- MFP_ARP,
- true,
- NXM_NX_ARP_SHA, "NXM_NX_ARP_SHA",
- OXM_OF_ARP_SHA, "OXM_OF_ARP_SHA", OFP12_VERSION,
- OFPUTIL_P_NXM_OXM_ANY,
- OFPUTIL_P_NXM_OXM_ANY,
- -1,
- }, {
- MFF_ARP_THA, "arp_tha", NULL,
- MF_FIELD_SIZES(mac),
- MFM_FULLY,
- MFS_ETHERNET,
- MFP_ARP,
- true,
- NXM_NX_ARP_THA, "NXM_NX_ARP_THA",
- OXM_OF_ARP_THA, "OXM_OF_ARP_THA", OFP12_VERSION,
- OFPUTIL_P_NXM_OXM_ANY,
- OFPUTIL_P_NXM_OXM_ANY,
- -1,
- },
-
- /* ## -- ## */
- /* ## L4 ## */
- /* ## -- ## */
-
- {
- MFF_TCP_SRC, "tcp_src", "tp_src",
- MF_FIELD_SIZES(be16),
- MFM_FULLY,
- MFS_DECIMAL,
- MFP_TCP,
- true,
- NXM_OF_TCP_SRC, "NXM_OF_TCP_SRC",
- OXM_OF_TCP_SRC, "OXM_OF_TCP_SRC", OFP12_VERSION,
- OFPUTIL_P_ANY,
- OFPUTIL_P_NXM_OXM_ANY,
- -1,
- }, {
- MFF_TCP_DST, "tcp_dst", "tp_dst",
- MF_FIELD_SIZES(be16),
- MFM_FULLY,
- MFS_DECIMAL,
- MFP_TCP,
- true,
- NXM_OF_TCP_DST, "NXM_OF_TCP_DST",
- OXM_OF_TCP_DST, "OXM_OF_TCP_DST", OFP12_VERSION,
- OFPUTIL_P_ANY,
- OFPUTIL_P_NXM_OXM_ANY,
- -1,
- }, {
- MFF_TCP_FLAGS, "tcp_flags", NULL,
- 2, 12,
- MFM_FULLY,
- MFS_TCP_FLAGS,
- MFP_TCP,
- false,
- NXM_NX_TCP_FLAGS, "NXM_NX_TCP_FLAGS",
- OXM_OF_TCP_FLAGS, "OXM_OF_TCP_FLAGS", OFP15_VERSION,
- OFPUTIL_P_NXM_OXM_ANY,
- OFPUTIL_P_NXM_OXM_ANY,
- -1,
- },
-
- {
- MFF_UDP_SRC, "udp_src", NULL,
- MF_FIELD_SIZES(be16),
- MFM_FULLY,
- MFS_DECIMAL,
- MFP_UDP,
- true,
- NXM_OF_UDP_SRC, "NXM_OF_UDP_SRC",
- OXM_OF_UDP_SRC, "OXM_OF_UDP_SRC", OFP12_VERSION,
- OFPUTIL_P_ANY,
- OFPUTIL_P_NXM_OXM_ANY,
- -1,
- }, {
- MFF_UDP_DST, "udp_dst", NULL,
- MF_FIELD_SIZES(be16),
- MFM_FULLY,
- MFS_DECIMAL,
- MFP_UDP,
- true,
- NXM_OF_UDP_DST, "NXM_OF_UDP_DST",
- OXM_OF_UDP_DST, "OXM_OF_UDP_DST", OFP12_VERSION,
- OFPUTIL_P_ANY,
- OFPUTIL_P_NXM_OXM_ANY,
- -1,
- },
-
- {
- MFF_SCTP_SRC, "sctp_src", NULL,
- MF_FIELD_SIZES(be16),
- MFM_FULLY,
- MFS_DECIMAL,
- MFP_SCTP,
- true,
- OXM_OF_SCTP_SRC, "OXM_OF_SCTP_SRC",
- OXM_OF_SCTP_SRC, "OXM_OF_SCTP_SRC", OFP12_VERSION,
- OFPUTIL_P_NXM_OF11_UP,
- OFPUTIL_P_NXM_OXM_ANY,
- -1,
- }, {
- MFF_SCTP_DST, "sctp_dst", NULL,
- MF_FIELD_SIZES(be16),
- MFM_FULLY,
- MFS_DECIMAL,
- MFP_SCTP,
- true,
- OXM_OF_SCTP_DST, "OXM_OF_SCTP_DST",
- OXM_OF_SCTP_DST, "OXM_OF_SCTP_DST", OFP12_VERSION,
- OFPUTIL_P_NXM_OF11_UP,
- OFPUTIL_P_NXM_OXM_ANY,
- -1,
- },
-
- {
- MFF_ICMPV4_TYPE, "icmp_type", NULL,
- MF_FIELD_SIZES(u8),
- MFM_NONE,
- MFS_DECIMAL,
- MFP_ICMPV4,
- false,
- NXM_OF_ICMP_TYPE, "NXM_OF_ICMP_TYPE",
- OXM_OF_ICMPV4_TYPE, "OXM_OF_ICMPV4_TYPE", OFP12_VERSION,
- OFPUTIL_P_ANY,
- OFPUTIL_P_NONE,
- -1,
- }, {
- MFF_ICMPV4_CODE, "icmp_code", NULL,
- MF_FIELD_SIZES(u8),
- MFM_NONE,
- MFS_DECIMAL,
- MFP_ICMPV4,
- false,
- NXM_OF_ICMP_CODE, "NXM_OF_ICMP_CODE",
- OXM_OF_ICMPV4_CODE, "OXM_OF_ICMPV4_CODE", OFP12_VERSION,
- OFPUTIL_P_ANY,
- OFPUTIL_P_NONE,
- -1,
- },
-
- {
- MFF_ICMPV6_TYPE, "icmpv6_type", NULL,
- MF_FIELD_SIZES(u8),
- MFM_NONE,
- MFS_DECIMAL,
- MFP_ICMPV6,
- false,
- NXM_NX_ICMPV6_TYPE, "NXM_NX_ICMPV6_TYPE",
- OXM_OF_ICMPV6_TYPE, "OXM_OF_ICMPV6_TYPE", OFP12_VERSION,
- OFPUTIL_P_NXM_OXM_ANY,
- OFPUTIL_P_NONE,
- -1,
- }, {
- MFF_ICMPV6_CODE, "icmpv6_code", NULL,
- MF_FIELD_SIZES(u8),
- MFM_NONE,
- MFS_DECIMAL,
- MFP_ICMPV6,
- false,
- NXM_NX_ICMPV6_CODE, "NXM_NX_ICMPV6_CODE",
- OXM_OF_ICMPV6_CODE, "OXM_OF_ICMPV6_CODE", OFP12_VERSION,
- OFPUTIL_P_NXM_OXM_ANY,
- OFPUTIL_P_NONE,
- -1,
- },
-
- /* ## ---- ## */
- /* ## L"5" ## */
- /* ## ---- ## */
-
- {
- MFF_ND_TARGET, "nd_target", NULL,
- MF_FIELD_SIZES(ipv6),
- MFM_FULLY,
- MFS_IPV6,
- MFP_ND,
- false,
- NXM_NX_ND_TARGET, "NXM_NX_ND_TARGET",
- OXM_OF_IPV6_ND_TARGET, "OXM_OF_IPV6_ND_TARGET", OFP12_VERSION,
- OFPUTIL_P_NXM_OXM_ANY,
- OFPUTIL_P_NXM_OXM_ANY,
- -1,
- }, {
- MFF_ND_SLL, "nd_sll", NULL,
- MF_FIELD_SIZES(mac),
- MFM_FULLY,
- MFS_ETHERNET,
- MFP_ND_SOLICIT,
- false,
- NXM_NX_ND_SLL, "NXM_NX_ND_SLL",
- OXM_OF_IPV6_ND_SLL, "OXM_OF_IPV6_ND_SLL", OFP12_VERSION,
- OFPUTIL_P_NXM_OXM_ANY,
- OFPUTIL_P_NXM_OXM_ANY,
- -1,
- }, {
- MFF_ND_TLL, "nd_tll", NULL,
- MF_FIELD_SIZES(mac),
- MFM_FULLY,
- MFS_ETHERNET,
- MFP_ND_ADVERT,
- false,
- NXM_NX_ND_TLL, "NXM_NX_ND_TLL",
- OXM_OF_IPV6_ND_TLL, "OXM_OF_IPV6_ND_TLL", OFP12_VERSION,
- OFPUTIL_P_NXM_OXM_ANY,
- OFPUTIL_P_NXM_OXM_ANY,
- -1,
- }
+#include "meta-flow.inc"
};
/* Maps an NXM or OXM header value to an mf_field. */
{
if (!mask || is_all_ones(mask, mf->n_bytes)) {
mf_set_value(mf, value, match);
- return mf->usable_protocols;
+ return mf->usable_protocols_exact;
} else if (is_all_zeros(mask, mf->n_bytes)) {
mf_set_wild(mf, match);
return OFPUTIL_P_ANY;
case MFF_IPV4_SRC:
match_set_nw_src_masked(match, value->be32, mask->be32);
- goto cidr_check;
+ break;
case MFF_IPV4_DST:
match_set_nw_dst_masked(match, value->be32, mask->be32);
- goto cidr_check;
+ break;
case MFF_IPV6_SRC:
match_set_ipv6_src_masked(match, &value->ipv6, &mask->ipv6);
case MFF_ARP_SPA:
match_set_nw_src_masked(match, value->be32, mask->be32);
- goto cidr_check;
+ break;
case MFF_ARP_TPA:
match_set_nw_dst_masked(match, value->be32, mask->be32);
- goto cidr_check;
+ break;
case MFF_TCP_SRC:
case MFF_UDP_SRC:
OVS_NOT_REACHED();
}
- return mf->usable_protocols_bitwise;
-
-cidr_check:
- return ip_is_cidr(mask->be32) ? mf->usable_protocols :
- mf->usable_protocols_bitwise;
+ return ((mf->usable_protocols_bitwise == mf->usable_protocols_cidr
+ || ip_is_cidr(mask->be32))
+ ? mf->usable_protocols_cidr
+ : mf->usable_protocols_bitwise);
}
static enum ofperr
struct ds;
struct match;
-/* The comment on each of these indicates the member in "union mf_value" used
- * to represent its value. */
+/* Open vSwitch fields
+ * ===================
+ *
+ * A "field" is a property of a packet. Most familiarly, "data fields" are
+ * fields that can be extracted from a packet.
+ *
+ * Some data fields are always present as a consequence of the basic networking
+ * technology in use. Ethernet is the assumed base technology for current
+ * versions of OpenFlow and Open vSwitch, so Ethernet header fields are always
+ * available.
+ *
+ * Other data fields are not always present. A packet contains ARP fields, for
+ * example, only when its Ethernet header indicates the Ethertype for ARP,
+ * 0x0806. We say that a field is "applicable" when it is it present in a
+ * packet, and "inapplicable" when it is not, and refer to the conditions that
+ * determine whether a field is applicable as "prerequisites". Some
+ * VLAN-related fields are a special case: these fields are always applicable,
+ * but have a designated value or bit that indicates whether a VLAN header is
+ * present, with the remaining values or bits indicating the VLAN header's
+ * content (if it is present). See MFF_VLAN_TCI for an example.
+ *
+ * Conceptually, an inapplicable field does not have a value, not even a
+ * nominal ``value'' such as all-zero-bits. In many circumstances, OpenFlow
+ * and Open vSwitch allow references only to applicable fields. For example,
+ * one may match a given field only if the match includes the field's
+ * prerequisite, e.g. matching an ARP field is only allowed if one also matches
+ * on Ethertype 0x0806.
+ *
+ * (Practically, however, OVS represents a field's value as some fixed member
+ * in its "struct flow", so accessing that member will obtain some value. Some
+ * members are used for more than one purpose, e.g. the "tp_src" member
+ * represents the TCP, UDP, and SCTP source port, so the value read may not
+ * even make sense. For this reason, it is important to know whether a field's
+ * prerequisites are satisfied before attempting to read it.)
+ *
+ * Sometimes a packet may contain multiple instances of a header. For example,
+ * a packet may contain multiple VLAN or MPLS headers, and tunnels can cause
+ * any data field to recur. OpenFlow and Open vSwitch do not address these
+ * cases uniformly. For VLAN and MPLS headers, only the outermost header is
+ * accessible, so that inner headers may be accessed only by ``popping''
+ * (removing) the outer header. (Open vSwitch supports only a single VLAN
+ * header in any case.) For tunnels, e.g. GRE or VXLAN, the outer header and
+ * inner headers are treated as different data fields.
+ *
+ * OpenFlow and Open vSwitch support some fields other than data fields.
+ * "Metadata fields" relate to the origin or treatment of a packet, but they
+ * are not extracted from the packet data itself. One example is the physical
+ * port on which a packet arrived at the switch. "Register fields" act like
+ * variables: they give an OpenFlow switch space for temporary storage while
+ * processing a packet. Existing metadata and register fields have no
+ * prerequisites.
+ *
+ * A field's value consists of an integral number of bytes. Most data fields
+ * are copied directly from protocol headers, e.g. at layer 2, MFF_ETH_SRC is
+ * copied from the Ethernet source address and MFF_ETH_DST from the destination
+ * address. Other data fields are copied from a packet with padding, usually
+ * with zeros and in the most significant positions (see e.g. MFF_MPLS_LABEL)
+ * but not always (see e.g. MFF_IP_DSCP). A final category of data fields is
+ * transformed in other ways as they are copied from the packets, to make them
+ * more useful for matching, e.g. MFF_IP_FRAG describes whether a packet is a
+ * fragment but it is not copied directly from the IP header.
+ *
+ *
+ * Field specifications
+ * ====================
+ *
+ * Each of the enumeration values below represents a field. The comments
+ * preceding each enum must be in a stylized form that is parsed at compile
+ * time by the extract-ofp-fields program. The comment itself consists of a
+ * series of paragraphs separate by blank lines. The paragraphs consist of:
+ *
+ * - The first paragraph gives the user-visible name of the field as a
+ * quoted string. This is the name used for parsing and formatting the
+ * field.
+ *
+ * For historical reasons, some fields have an additional name that is
+ * accepted as an alternative in parsing. This name, when there is one,
+ * is given as a quoted string in parentheses along with "aka". For
+ * example:
+ *
+ * "tun_id" (aka "tunnel_id").
+ *
+ * New fields should have only one name.
+ *
+ * - Any number of paragraphs of free text that describe the field. This
+ * is meant for human readers, so extract-ofp-fields ignores it.
+ *
+ * - A final paragraph that consists of a series of key-value pairs, one
+ * per line, in the form "key: value." where the period at the end of the
+ * line is a mandatory part of the syntax.
+ *
+ * Every field must specify the following key-value pairs:
+ *
+ * Type:
+ *
+ * The format and size of the field's value. Some possible values are
+ * generic:
+ *
+ * u8: A one-byte field.
+ * be16: A two-byte field.
+ * be32: A four-byte field.
+ * be64: An eight-byte field.
+ *
+ * The remaining values imply more about the value's semantics, though OVS
+ * does not currently take advantage of this additional information:
+ *
+ * MAC: A six-byte field whose value is an Ethernet address.
+ * IPv6: A 16-byte field whose value is an IPv6 address.
+ *
+ * Maskable:
+ *
+ * Either "bitwise", if OVS supports matching any subset of bits in the
+ * field, or "no", if OVS only supports matching or wildcarding the entire
+ * field.
+ *
+ * Formatting:
+ *
+ * Explains how a field's value is formatted and parsed for human
+ * consumption. Some of the options are fairly generally useful:
+ *
+ * decimal: Formats the value as a decimal number. On parsing, accepts
+ * decimal (with no prefix), hexadecimal with 0x prefix, or octal
+ * with 0 prefix.
+ *
+ * hexadecimal: Same as decimal except nonzero values are formatted in
+ * hex with 0x prefix. The default for parsing is *not* hexadecimal:
+ * only with a 0x prefix is the input in hexadecimal.
+ *
+ * Ethernet: Formats and accepts the common format xx:xx:xx:xx:xx:xx.
+ * 6-byte fields only.
+ *
+ * IPv4: Formats and accepts the common format w.x.y.z. 4-byte fields
+ * only.
+ *
+ * IPv6: Formats and accepts the common IPv6 formats. 16-byte fields
+ * only.
+ *
+ * OpenFlow 1.0 port: Accepts an OpenFlow well-known port name
+ * (e.g. "IN_PORT") in uppercase or lowercase, or a 16-bit port
+ * number in decimal. Formats ports using their well-known names in
+ * uppercase, or in decimal otherwise. 2-byte fields only.
+ *
+ * OpenFlow 1.1+ port: Same syntax as for OpenFlow 1.0 ports but for
+ * 4-byte OpenFlow 1.1+ port number fields.
+ *
+ * Others are very specific to particular fields:
+ *
+ * frag: One of the strings "no", "first", "later", "yes", "not_later"
+ * describing which IPv4/v6 fragments are matched.
+ *
+ * tunnel flags: Any number of the strings "df", "csum", "key", or
+ * "oam" separated by "|".
+ *
+ * TCP flags: See the description of tcp_flags in ovs-ofctl(8).
+ *
+ * Prerequisites:
+ *
+ * The field's prerequisites. The values should be straightfoward.
+ *
+ * Access:
+ *
+ * Either "read-only", for a field that cannot be changed via OpenFlow, or
+ * "read/write" for a modifiable field.
+ *
+ * NXM:
+ *
+ * If the field has an NXM field assignment, then this specifies the NXM
+ * name of the field (e.g. "NXM_OF_ETH_SRC"), followed by its nxm_type in
+ * parentheses, followed by "since v<x>.<y>" specifying the version of Open
+ * vSwitch that first supported this field in NXM (e.g. "since v1.1" if it
+ * was introduced in Open vSwitch 1.1).
+ *
+ * The NXM name must begin with NXM_OF_ or NXM_NX_. This allows OVS to
+ * determine the correct NXM class.
+ *
+ * If the field does not have an NXM field assignment, specify "none".
+ *
+ * OXM:
+ *
+ * If the field has an OXM field assignment, then this specifies the OXM
+ * name of the field (e.g. "OXM_OF_ETH_SRC"), followed by its nxm_type in
+ * parentheses, followed by "since OF<a>.<b> v<x>.<y>" specifying the
+ * versions of OpenFlow and Open vSwitch that first supported this field in
+ * OXM (e.g. "since OF1.3 and v1.10" if it was introduced in OpenFlow 1.3
+ * and first supported by Open vSwitch in version 1.10).
+ *
+ * OVS uses the start of the OXM field name to determine the correct OXM
+ * class. To support a new OXM class, edit the mapping table in
+ * build-aux/extract-ofp-fields.
+ *
+ * If the field does not have an OXM field assignment, specify "none".
+ *
+ * The following key-value pairs are optional. Open vSwitch already supports
+ * all the fields to which they apply, so new fields should probably not
+ * include these pairs:
+ *
+ * OF1.0:
+ *
+ * Specify this as "exact match" if OpenFlow 1.0 can match or wildcard the
+ * entire field, or as "CIDR mask" if OpenFlow 1.0 can match any CIDR
+ * prefix of the field. (OpenFlow 1.0 did not support bitwise matching.)
+ * Omit, if OpenFlow 1.0 did not support this field.
+ *
+ * OF1.1:
+ *
+ * Specify this as "exact match" if OpenFlow 1.1 can match or wildcard the
+ * entire field, or as "bitwise" if OpenFlow 1.1 can match any subset of
+ * bits in the field. Omit, if OpenFlow 1.1 did not support this field.
+ *
+ * The following key-value pair is optional:
+ *
+ * Prefix lookup member:
+ *
+ * If this field makes sense for use with classifier_set_prefix_fields(),
+ * specify the name of the "struct flow" member that corresponds to the
+ * field.
+ *
+ * Finally, a few "register" fields have very similar names and purposes,
+ * e.g. MFF_REG0 through MFF_REG7. For these, the comments may be merged
+ * together using <N> as a metasyntactic variable for the numeric suffix.
+ * Lines in the comment that are specific to one of the particular fields by
+ * writing, e.g. <1>, to consider that line only for e.g. MFF_REG1.
+ */
+
enum OVS_PACKED_ENUM mf_field_id {
- /* Metadata. */
- MFF_DP_HASH, /* be32 */
- MFF_RECIRC_ID, /* be32 */
- MFF_TUN_ID, /* be64 */
- MFF_TUN_SRC, /* be32 */
- MFF_TUN_DST, /* be32 */
- MFF_TUN_FLAGS, /* be16 */
- MFF_TUN_TTL, /* u8 */
- MFF_TUN_TOS, /* u8 */
- MFF_METADATA, /* be64 */
- MFF_IN_PORT, /* be16 */
- MFF_IN_PORT_OXM, /* be32 */
- MFF_SKB_PRIORITY, /* be32 */
- MFF_PKT_MARK, /* be32 */
+/* ## -------- ## */
+/* ## Metadata ## */
+/* ## -------- ## */
+
+ /* "dp_hash".
+ *
+ * Flow hash computed in the datapath. Internal use only, not programmable
+ * from controller.
+ *
+ * Type: be32.
+ * Maskable: bitwise.
+ * Formatting: hexadecimal.
+ * Prerequisites: none.
+ * Access: read-only.
+ * NXM: NXM_NX_DP_HASH(35) since v2.2.
+ * OXM: none.
+ */
+ MFF_DP_HASH,
+
+ /* "recirc_id".
+ *
+ * ID for recirculation. The value 0 is reserved for initially received
+ * packets. Internal use only, not programmable from controller.
+ *
+ * Type: be32.
+ * Maskable: no.
+ * Formatting: decimal.
+ * Prerequisites: none.
+ * Access: read-only.
+ * NXM: NXM_NX_RECIRC_ID(36) since v2.2.
+ * OXM: none.
+ */
+ MFF_RECIRC_ID,
+
+ /* "tun_id" (aka "tunnel_id").
+ *
+ * The "key" or "tunnel ID" or "VNI" in a packet received via a keyed
+ * tunnel. For protocols in which the key is shorter than 64 bits, the key
+ * is stored in the low bits and the high bits are zeroed. For non-keyed
+ * tunnels and packets not received via a tunnel, the value is 0.
+ *
+ * Type: be64.
+ * Maskable: bitwise.
+ * Formatting: hexadecimal.
+ * Prerequisites: none.
+ * Access: read/write.
+ * NXM: NXM_NX_TUN_ID(16) since v1.1.
+ * OXM: OXM_OF_TUNNEL_ID(38) since OF1.3 and v1.10.
+ * Prefix lookup member: tunnel.tun_id.
+ */
+ MFF_TUN_ID,
+
+ /* "tun_src".
+ *
+ * The IPv4 source address in the outer IP header of a tunneled packet.
+ *
+ * For non-tunneled packets, the value is 0.
+ *
+ * Type: be32.
+ * Maskable: bitwise.
+ * Formatting: IPv4.
+ * Prerequisites: none.
+ * Access: read/write.
+ * NXM: NXM_NX_TUN_IPV4_SRC(31) since v2.0.
+ * OXM: none.
+ * Prefix lookup member: tunnel.ip_src.
+ */
+ MFF_TUN_SRC,
+
+ /* "tun_dst".
+ *
+ * The IPv4 destination address in the outer IP header of a tunneled
+ * packet.
+ *
+ * For non-tunneled packets, the value is 0.
+ *
+ * Type: be32.
+ * Maskable: bitwise.
+ * Formatting: IPv4.
+ * Prerequisites: none.
+ * Access: read/write.
+ * NXM: NXM_NX_TUN_IPV4_DST(32) since v2.0.
+ * OXM: none.
+ * Prefix lookup member: tunnel.ip_dst.
+ */
+ MFF_TUN_DST,
+
+ /* "tun_flags".
+ *
+ * Combination of FLOW_TNL_F_* bitmapped flags that indicate properties of
+ * a tunneled packet. Internal use only, not programmable from controller.
+ *
+ * For non-tunneled packets, the value is 0.
+ *
+ * Type: be16.
+ * Maskable: no.
+ * Formatting: tunnel flags.
+ * Prerequisites: none.
+ * Access: read-only.
+ * NXM: none.
+ * OXM: none.
+ */
+ MFF_TUN_FLAGS,
+
+ /* "tun_ttl".
+ *
+ * The TTL in the outer IP header of a tunneled packet. Internal use only,
+ * not programmable from controller.
+ *
+ * For non-tunneled packets, the value is 0.
+ *
+ * Type: u8.
+ * Maskable: no.
+ * Formatting: decimal.
+ * Prerequisites: none.
+ * Access: read-only.
+ * NXM: none.
+ * OXM: none.
+ */
+ MFF_TUN_TTL,
+
+ /* "tun_tos".
+ *
+ * The ToS value in the outer IP header of a tunneled packet. Internal use
+ * only, not programmable from controller.
+ *
+ * Type: u8.
+ * Maskable: no.
+ * Formatting: decimal.
+ * Prerequisites: none.
+ * Access: read-only.
+ * NXM: none.
+ * OXM: none.
+ */
+ MFF_TUN_TOS,
+
+ /* "metadata".
+ *
+ * A scratch pad value standardized in OpenFlow 1.1+. Initially zero, at
+ * the beginning of the pipeline.
+ *
+ * Type: be64.
+ * Maskable: bitwise.
+ * Formatting: hexadecimal.
+ * Prerequisites: none.
+ * Access: read/write.
+ * NXM: none.
+ * OXM: OXM_OF_METADATA(2) since OF1.2 and v1.8.
+ * OF1.1: bitwise mask.
+ */
+ MFF_METADATA,
+
+ /* "in_port".
+ *
+ * 16-bit (OpenFlow 1.0) view of the physical or virtual port on which the
+ * packet was received.
+ *
+ * Type: be16.
+ * Maskable: no.
+ * Formatting: OpenFlow 1.0 port.
+ * Prerequisites: none.
+ * Access: read/write.
+ * NXM: NXM_OF_IN_PORT(0) since v1.1.
+ * OXM: none.
+ * OF1.0: exact match.
+ * OF1.1: exact match.
+ */
+ MFF_IN_PORT,
+
+ /* "in_port_oxm".
+ *
+ * 32-bit (OpenFlow 1.1+) view of the physical or virtual port on which the
+ * packet was received.
+ *
+ * Type: be32.
+ * Maskable: no.
+ * Formatting: OpenFlow 1.1+ port.
+ * Prerequisites: none.
+ * Access: read/write.
+ * NXM: none.
+ * OXM: OXM_OF_IN_PORT(0) since OF1.2 and v1.7.
+ * OF1.1: exact match.
+ */
+ MFF_IN_PORT_OXM,
+
+ /* "skb_priority".
+ *
+ * Designates the queue to which output will be directed. The value in
+ * this field is not necessarily the OpenFlow queue number; with the Linux
+ * kernel switch, it instead has a pair of subfields designating the
+ * "major" and "minor" numbers of a Linux kernel qdisc handle.
+ *
+ * This field is "semi-internal" in that it can be set with the "set_queue"
+ * action but not matched or read or written other ways.
+ *
+ * Type: be32.
+ * Maskable: no.
+ * Formatting: hexadecimal.
+ * Prerequisites: none.
+ * Access: read-only.
+ * NXM: none.
+ * OXM: none.
+ */
+ MFF_SKB_PRIORITY,
+
+ /* "pkt_mark".
+ *
+ * Packet metadata mark. The mark may be passed into other system
+ * components in order to facilitate interaction between subsystems. On
+ * Linux this corresponds to struct sk_buff's "skb_mark" member but the
+ * exact implementation is platform-dependent.
+ *
+ * Type: be32.
+ * Maskable: bitwise.
+ * Formatting: hexadecimal.
+ * Prerequisites: none.
+ * Access: read/write.
+ * NXM: NXM_NX_PKT_MARK(33) since v2.0.
+ * OXM: none.
+ */
+ MFF_PKT_MARK,
#if FLOW_N_REGS == 8
- MFF_REG0, /* be32 */
- MFF_REG1, /* be32 */
- MFF_REG2, /* be32 */
- MFF_REG3, /* be32 */
- MFF_REG4, /* be32 */
- MFF_REG5, /* be32 */
- MFF_REG6, /* be32 */
- MFF_REG7, /* be32 */
+ /* "reg<N>".
+ *
+ * Nicira extension scratch pad register with initial value 0.
+ *
+ * Type: be32.
+ * Maskable: bitwise.
+ * Formatting: hexadecimal.
+ * Prerequisites: none.
+ * Access: read/write.
+ * NXM: NXM_NX_REG0(0) since v1.1. <0>
+ * NXM: NXM_NX_REG1(1) since v1.1. <1>
+ * NXM: NXM_NX_REG2(2) since v1.1. <2>
+ * NXM: NXM_NX_REG3(3) since v1.1. <3>
+ * NXM: NXM_NX_REG4(4) since v1.3. <4>
+ * NXM: NXM_NX_REG5(5) since v1.7. <5>
+ * NXM: NXM_NX_REG6(6) since v1.7. <6>
+ * NXM: NXM_NX_REG7(7) since v1.7. <7>
+ * OXM: none.
+ */
+ MFF_REG0,
+ MFF_REG1,
+ MFF_REG2,
+ MFF_REG3,
+ MFF_REG4,
+ MFF_REG5,
+ MFF_REG6,
+ MFF_REG7,
#else
#error "Need to update MFF_REG* to match FLOW_N_REGS"
#endif
#if FLOW_N_XREGS == 4
- MFF_XREG0, /* be64 */
- MFF_XREG1, /* be64 */
- MFF_XREG2, /* be64 */
- MFF_XREG3, /* be64 */
+ /* "xreg<N>".
+ *
+ * OpenFlow 1.5 (draft) ``extended register". Each extended register
+ * overlays two of the Nicira extension 32-bit registers: xreg0 overlays
+ * reg0 and reg1, with reg0 supplying the most-significant bits of xreg0
+ * and reg1 the least-significant. xreg1 similarly overlays reg2 and reg3,
+ * and so on.
+ *
+ * Type: be64.
+ * Maskable: bitwise.
+ * Formatting: hexadecimal.
+ * Prerequisites: none.
+ * Access: read/write.
+ * NXM: none.
+ * OXM: OXM_OF_PKT_REG<N>(<N>) since OF1.5 and v2.4.
+ */
+ MFF_XREG0,
+ MFF_XREG1,
+ MFF_XREG2,
+ MFF_XREG3,
#else
#error "Need to update MFF_REG* to match FLOW_N_XREGS"
#endif
- /* L2. */
- MFF_ETH_SRC, /* mac */
- MFF_ETH_DST, /* mac */
- MFF_ETH_TYPE, /* be16 */
-
- MFF_VLAN_TCI, /* be16 */
- MFF_DL_VLAN, /* be16 (OpenFlow 1.0 compatibility) */
- MFF_VLAN_VID, /* be16 (OpenFlow 1.2 compatibility) */
- MFF_DL_VLAN_PCP, /* u8 (OpenFlow 1.0 compatibility) */
- MFF_VLAN_PCP, /* be16 (OpenFlow 1.2 compatibility) */
-
- /* L2.5 */
- MFF_MPLS_LABEL, /* be32 */
- MFF_MPLS_TC, /* u8 */
- MFF_MPLS_BOS, /* u8 */
-
- /* L3. */
- /* Update mf_is_l3_or_higher() if MFF_IPV4_SRC is
- * no longer the first element for a field of layer 3 or higher */
- MFF_IPV4_SRC, /* be32 */
- MFF_IPV4_DST, /* be32 */
-
- MFF_IPV6_SRC, /* ipv6 */
- MFF_IPV6_DST, /* ipv6 */
- MFF_IPV6_LABEL, /* be32 */
-
- /* The IPv4/IPv6 DSCP field has two different views:
- *
- * - MFF_IP_DSCP has the DSCP in bits 2-7, their bit positions in the
- * IPv4 and IPv6 "traffic class" field, as used in OpenFlow 1.0 and 1.1
- * flow format and in NXM's NXM_OF_IP_TOS
- *
- * - MFF_IP_DSCP has the DSCP in bits 0-5, shifted right two bits from
- * their positions in the IPv4 and IPv6 "traffic class" field, as used
- * in OpenFlow 1.2+ OXM's OXM_OF_IP_DSCP. */
- MFF_IP_PROTO, /* u8 (used for IPv4 or IPv6) */
- MFF_IP_DSCP, /* u8 (used for IPv4 or IPv6) */
- MFF_IP_DSCP_SHIFTED, /* u8 (used for IPv4 or IPv6) (OF1.2 compat) */
- MFF_IP_ECN, /* u8 (used for IPv4 or IPv6) */
- MFF_IP_TTL, /* u8 (used for IPv4 or IPv6) */
- MFF_IP_FRAG, /* u8 (used for IPv4 or IPv6) */
-
- MFF_ARP_OP, /* be16 */
- MFF_ARP_SPA, /* be32 */
- MFF_ARP_TPA, /* be32 */
- MFF_ARP_SHA, /* mac */
- MFF_ARP_THA, /* mac */
-
- /* L4. */
- MFF_TCP_SRC, /* be16 (used for IPv4 or IPv6) */
- MFF_TCP_DST, /* be16 (used for IPv4 or IPv6) */
- MFF_TCP_FLAGS, /* be16, 12 bits (4 MSB zeroed,
- * used for IPv4 or IPv6) */
-
- MFF_UDP_SRC, /* be16 (used for IPv4 or IPv6) */
- MFF_UDP_DST, /* be16 (used for IPv4 or IPv6) */
-
- MFF_SCTP_SRC, /* be16 (used for IPv4 or IPv6) */
- MFF_SCTP_DST, /* be16 (used for IPv4 or IPv6) */
-
- MFF_ICMPV4_TYPE, /* u8 */
- MFF_ICMPV4_CODE, /* u8 */
-
- MFF_ICMPV6_TYPE, /* u8 */
- MFF_ICMPV6_CODE, /* u8 */
-
- /* ICMPv6 Neighbor Discovery. */
- MFF_ND_TARGET, /* ipv6 */
- MFF_ND_SLL, /* mac */
- MFF_ND_TLL, /* mac */
+/* ## -------- ## */
+/* ## Ethernet ## */
+/* ## -------- ## */
+
+ /* "eth_src" (aka "dl_src").
+ *
+ * Source address in Ethernet header.
+ *
+ * This field was not maskable before Open vSwitch 1.8.
+ *
+ * Type: MAC.
+ * Maskable: bitwise.
+ * Formatting: Ethernet.
+ * Prerequisites: none.
+ * Access: read/write.
+ * NXM: NXM_OF_ETH_SRC(2) since v1.1.
+ * OXM: OXM_OF_ETH_SRC(4) since OF1.2 and v1.7.
+ * OF1.0: exact match.
+ * OF1.1: bitwise mask.
+ */
+ MFF_ETH_SRC,
+
+ /* "eth_dst" (aka "dl_dst").
+ *
+ * Destination address in Ethernet header.
+ *
+ * Before Open vSwitch 1.8, the allowed masks were restricted to
+ * 00:00:00:00:00:00, fe:ff:ff:ff:ff:ff, 01:00:00:00:00:00,
+ * ff:ff:ff:ff:ff:ff.
+ *
+ * Type: MAC.
+ * Maskable: bitwise.
+ * Formatting: Ethernet.
+ * Prerequisites: none.
+ * Access: read/write.
+ * NXM: NXM_OF_ETH_DST(1) since v1.1.
+ * OXM: OXM_OF_ETH_DST(3) since OF1.2 and v1.7.
+ * OF1.0: exact match.
+ * OF1.1: bitwise mask.
+ */
+ MFF_ETH_DST,
+
+ /* "eth_type" (aka "dl_type").
+ *
+ * Packet's Ethernet type.
+ *
+ * For an Ethernet II packet this is taken from the Ethernet header. For
+ * an 802.2 LLC+SNAP header with OUI 00-00-00 this is taken from the SNAP
+ * header. A packet that has neither format has value 0x05ff
+ * (OFP_DL_TYPE_NOT_ETH_TYPE).
+ *
+ * For a packet with an 802.1Q header, this is the type of the encapsulated
+ * frame.
+ *
+ * Type: be16.
+ * Maskable: no.
+ * Formatting: hexadecimal.
+ * Prerequisites: none.
+ * Access: read-only.
+ * NXM: NXM_OF_ETH_TYPE(3) since v1.1.
+ * OXM: OXM_OF_ETH_TYPE(5) since OF1.2 and v1.7.
+ * OF1.0: exact match.
+ * OF1.1: exact match.
+ */
+ MFF_ETH_TYPE,
+
+/* ## ---- ## */
+/* ## VLAN ## */
+/* ## ---- ## */
+
+/* It looks odd for vlan_tci, vlan_vid, and vlan_pcp to say that they are
+ * supported in OF1.0 and OF1.1, since the detailed semantics of these fields
+ * only apply to NXM or OXM. They are marked as supported for exact matches in
+ * OF1.0 and OF1.1 because exact matches on those fields can be successfully
+ * translated into the OF1.0 and OF1.1 flow formats. */
+
+ /* "vlan_tci".
+ *
+ * 802.1Q TCI.
+ *
+ * For a packet with an 802.1Q header, this is the Tag Control Information
+ * (TCI) field, with the CFI bit forced to 1. For a packet with no 802.1Q
+ * header, this has value 0.
+ *
+ * This field can be used in various ways:
+ *
+ * - If it is not constrained at all, the nx_match matches packets
+ * without an 802.1Q header or with an 802.1Q header that has any TCI
+ * value.
+ *
+ * - Testing for an exact match with 0 matches only packets without an
+ * 802.1Q header.
+ *
+ * - Testing for an exact match with a TCI value with CFI=1 matches
+ * packets that have an 802.1Q header with a specified VID and PCP.
+ *
+ * - Testing for an exact match with a nonzero TCI value with CFI=0 does
+ * not make sense. The switch may reject this combination.
+ *
+ * - Testing with a specific VID and CFI=1, with nxm_mask=0x1fff, matches
+ * packets that have an 802.1Q header with that VID (and any PCP).
+ *
+ * - Testing with a specific PCP and CFI=1, with nxm_mask=0xf000, matches
+ * packets that have an 802.1Q header with that PCP (and any VID).
+ *
+ * - Testing with nxm_value=0, nxm_mask=0x0fff matches packets with no
+ * 802.1Q header or with an 802.1Q header with a VID of 0.
+ *
+ * - Testing with nxm_value=0, nxm_mask=0xe000 matches packets with no
+ * 802.1Q header or with an 802.1Q header with a PCP of 0.
+ *
+ * - Testing with nxm_value=0, nxm_mask=0xefff matches packets with no
+ * 802.1Q header or with an 802.1Q header with both VID and PCP of 0.
+ *
+ * Type: be16.
+ * Maskable: bitwise.
+ * Formatting: hexadecimal.
+ * Prerequisites: none.
+ * Access: read/write.
+ * NXM: NXM_OF_VLAN_TCI(4) since v1.1.
+ * OXM: none.
+ * OF1.0: exact match.
+ * OF1.1: exact match.
+ */
+ MFF_VLAN_TCI,
+
+ /* "dl_vlan" (OpenFlow 1.0).
+ *
+ * VLAN ID field. Zero if no 802.1Q header is present.
+ *
+ * Type: be16 (low 12 bits).
+ * Maskable: no.
+ * Formatting: decimal.
+ * Prerequisites: none.
+ * Access: read/write.
+ * NXM: none.
+ * OXM: none.
+ * OF1.0: exact match.
+ * OF1.1: exact match.
+ */
+ MFF_DL_VLAN,
+
+ /* "vlan_vid" (OpenFlow 1.2+).
+ *
+ * If an 802.1Q header is present, this field's value is 0x1000
+ * bitwise-or'd with the VLAN ID. If no 802.1Q is present, this field's
+ * value is 0.
+ *
+ * Type: be16 (low 12 bits).
+ * Maskable: bitwise.
+ * Formatting: decimal.
+ * Prerequisites: none.
+ * Access: read/write.
+ * NXM: none.
+ * OXM: OXM_OF_VLAN_VID(6) since OF1.2 and v1.7.
+ * OF1.0: exact match.
+ * OF1.1: exact match.
+ */
+ MFF_VLAN_VID,
+
+ /* "dl_vlan_pcp" (OpenFlow 1.0).
+ *
+ * VLAN priority (PCP) field. Zero if no 802.1Q header is present.
+ *
+ * Type: u8 (low 3 bits).
+ * Maskable: no.
+ * Formatting: decimal.
+ * Prerequisites: none.
+ * Access: read/write.
+ * NXM: none.
+ * OXM: none.
+ * OF1.0: exact match.
+ * OF1.1: exact match.
+ */
+ MFF_DL_VLAN_PCP,
+
+ /* "vlan_pcp" (OpenFlow 1.2+).
+ *
+ * VLAN priority (PCP) field. Zero if no 802.1Q header is present.
+ *
+ * Type: u8 (low 3 bits).
+ * Maskable: no.
+ * Formatting: decimal.
+ * Prerequisites: VLAN VID.
+ * Access: read/write.
+ * NXM: none.
+ * OXM: OXM_OF_VLAN_PCP(7) since OF1.2 and v1.7.
+ * OF1.0: exact match.
+ * OF1.1: exact match.
+ */
+ MFF_VLAN_PCP,
+
+/* ## ---- ## */
+/* ## MPLS ## */
+/* ## ---- ## */
+
+ /* "mpls_label".
+ *
+ * The outermost MPLS label, or 0 if no MPLS labels are present.
+ *
+ * Type: be32 (low 20 bits).
+ * Maskable: no.
+ * Formatting: decimal.
+ * Prerequisites: MPLS.
+ * Access: read/write.
+ * NXM: none.
+ * OXM: OXM_OF_MPLS_LABEL(34) since OF1.2 and v1.11.
+ * OF1.1: exact match.
+ */
+ MFF_MPLS_LABEL,
+
+ /* "mpls_tc".
+ *
+ * The outermost MPLS label's traffic control (TC) field, or 0 if no MPLS
+ * labels are present.
+ *
+ * Type: u8 (low 3 bits).
+ * Maskable: no.
+ * Formatting: decimal.
+ * Prerequisites: MPLS.
+ * Access: read/write.
+ * NXM: none.
+ * OXM: OXM_OF_MPLS_TC(35) since OF1.2 and v1.11.
+ * OF1.1: exact match.
+ */
+ MFF_MPLS_TC,
+
+ /* "mpls_bos".
+ *
+ * The outermost MPLS label's bottom of stack (BoS) field, or 0 if no MPLS
+ * labels are present.
+ *
+ * Type: u8 (low 1 bits).
+ * Maskable: no.
+ * Formatting: decimal.
+ * Prerequisites: MPLS.
+ * Access: read-only.
+ * NXM: none.
+ * OXM: OXM_OF_MPLS_BOS(36) since OF1.3 and v1.11.
+ */
+ MFF_MPLS_BOS,
+
+/* ## ---- ## */
+/* ## IPv4 ## */
+/* ## ---- ## */
+
+/* Update mf_is_l3_or_higher() if MFF_IPV4_SRC is no longer the first element
+ * for a field of layer 3 or higher */
+
+ /* "ip_src" (aka "nw_src").
+ *
+ * The source address in the IPv4 header.
+ *
+ * Before Open vSwitch 1.8, only CIDR masks were supported.
+ *
+ * Type: be32.
+ * Maskable: bitwise.
+ * Formatting: IPv4.
+ * Prerequisites: IPv4.
+ * Access: read/write.
+ * NXM: NXM_OF_IP_SRC(7) since v1.1.
+ * OXM: OXM_OF_IPV4_SRC(11) since OF1.2 and v1.7.
+ * OF1.0: CIDR mask.
+ * OF1.1: bitwise mask.
+ * Prefix lookup member: nw_src.
+ */
+ MFF_IPV4_SRC,
+
+ /* "ip_dst" (aka "nw_dst").
+ *
+ * The destination address in the IPv4 header.
+ *
+ * Before Open vSwitch 1.8, only CIDR masks were supported.
+ *
+ * Type: be32.
+ * Maskable: bitwise.
+ * Formatting: IPv4.
+ * Prerequisites: IPv4.
+ * Access: read/write.
+ * NXM: NXM_OF_IP_DST(8) since v1.1.
+ * OXM: OXM_OF_IPV4_DST(12) since OF1.2 and v1.7.
+ * OF1.0: CIDR mask.
+ * OF1.1: bitwise mask.
+ * Prefix lookup member: nw_dst.
+ */
+ MFF_IPV4_DST,
+
+/* ## ---- ## */
+/* ## IPv6 ## */
+/* ## ---- ## */
+
+ /* "ipv6_src".
+ *
+ * The source address in the IPv6 header.
+ *
+ * Type: IPv6.
+ * Maskable: bitwise.
+ * Formatting: IPv6.
+ * Prerequisites: IPv6.
+ * Access: read/write.
+ * NXM: NXM_NX_IPV6_SRC(19) since v1.1.
+ * OXM: OXM_OF_IPV6_SRC(26) since OF1.2 and v1.1.
+ * Prefix lookup member: ipv6_src.
+ */
+ MFF_IPV6_SRC,
+
+ /* "ipv6_dst".
+ *
+ * The destination address in the IPv6 header.
+ *
+ * Type: IPv6.
+ * Maskable: bitwise.
+ * Formatting: IPv6.
+ * Prerequisites: IPv6.
+ * Access: read/write.
+ * NXM: NXM_NX_IPV6_DST(20) since v1.1.
+ * OXM: OXM_OF_IPV6_DST(27) since OF1.2 and v1.1.
+ * Prefix lookup member: ipv6_dst.
+ */
+ MFF_IPV6_DST,
+
+ /* "ipv6_label".
+ *
+ * The flow label in the IPv6 header.
+ *
+ * Type: be32 (low 20 bits).
+ * Maskable: bitwise.
+ * Formatting: hexadecimal.
+ * Prerequisites: IPv6.
+ * Access: read-only.
+ * NXM: NXM_NX_IPV6_LABEL(27) since v1.4.
+ * OXM: OXM_OF_IPV6_FLABEL(28) since OF1.2 and v1.7.
+ */
+ MFF_IPV6_LABEL,
+
+/* ## ----------------------- ## */
+/* ## IPv4/IPv6 common fields ## */
+/* ## ----------------------- ## */
+
+ /* "nw_proto" (aka "ip_proto").
+ *
+ * The "protocol" byte in the IPv4 or IPv6 header.
+ *
+ * Type: u8.
+ * Maskable: no.
+ * Formatting: decimal.
+ * Prerequisites: IPv4/IPv6.
+ * Access: read-only.
+ * NXM: NXM_OF_IP_PROTO(6) since v1.1.
+ * OXM: OXM_OF_IP_PROTO(10) since OF1.2 and v1.7.
+ * OF1.0: exact match.
+ * OF1.1: exact match.
+ */
+ MFF_IP_PROTO,
+
+/* Both views of the DSCP below are marked as supported in all of the versions
+ * of OpenFlow because a match on either view can be successfully translated
+ * into every OpenFlow flow format. */
+
+ /* "nw_tos" (OpenFlow 1.0/1.1).
+ *
+ * The DSCP byte in the IPv4 header or the traffic class byte from the IPv6
+ * header, with the ECN bits forced to 0. (That is, bits 2-7 contain the
+ * type of service and bits 0-1 are zero.)
+ *
+ * Type: u8.
+ * Maskable: no.
+ * Formatting: decimal.
+ * Prerequisites: IPv4/IPv6.
+ * Access: read/write.
+ * NXM: NXM_OF_IP_TOS(5) since v1.1.
+ * OXM: none.
+ * OF1.0: exact match.
+ * OF1.1: exact match.
+ */
+ MFF_IP_DSCP,
+
+ /* "ip_dscp" (OpenFlow 1.2+).
+ *
+ * The DSCP byte in the IPv4 header or the traffic class byte from the IPv6
+ * header, shifted right 2 bits. (That is, bits 0-5 contain the type of
+ * service and bits 6-7 are zero.)
+ *
+ * Type: u8 (low 6 bits).
+ * Maskable: no.
+ * Formatting: decimal.
+ * Prerequisites: IPv4/IPv6.
+ * Access: read/write.
+ * NXM: none.
+ * OXM: OXM_OF_IP_DSCP(8) since OF1.2 and v1.7.
+ * OF1.0: exact match.
+ * OF1.1: exact match.
+ */
+ MFF_IP_DSCP_SHIFTED,
+
+ /* "nw_ecn" (aka "ip_ecn").
+ *
+ * The ECN bits in the IPv4 or IPv6 header.
+ *
+ * Type: u8 (low 2 bits).
+ * Maskable: no.
+ * Formatting: decimal.
+ * Prerequisites: IPv4/IPv6.
+ * Access: read/write.
+ * NXM: NXM_NX_IP_ECN(28) since v1.4.
+ * OXM: OXM_OF_IP_ECN(9) since OF1.2 and v1.7.
+ */
+ MFF_IP_ECN,
+
+ /* "nw_ttl".
+ *
+ * The time-to-live (TTL) in the IPv4 header or hop limit in the IPv6
+ * header.
+ *
+ * Type: u8.
+ * Maskable: no.
+ * Formatting: decimal.
+ * Prerequisites: IPv4/IPv6.
+ * Access: read/write.
+ * NXM: NXM_NX_IP_TTL(29) since v1.4.
+ * OXM: none.
+ */
+ MFF_IP_TTL,
+
+ /* "ip_frag".
+ *
+ * IP fragment information.
+ *
+ * This field has three possible values:
+ *
+ * - A packet that is not an IP fragment has value 0.
+ *
+ * - A packet that is an IP fragment with offset 0 (the first fragment)
+ * has bit 0 set and thus value 1.
+ *
+ * - A packet that is an IP fragment with nonzero offset has bits 0 and 1
+ * set and thus value 3.
+ *
+ * NX_IP_FRAG_ANY and NX_IP_FRAG_LATER are declared to symbolically
+ * represent the meanings of bits 0 and 1.
+ *
+ * The switch may reject matches against values that can never appear.
+ *
+ * It is important to understand how this field interacts with the OpenFlow
+ * IP fragment handling mode:
+ *
+ * - In OFPC_FRAG_DROP mode, the OpenFlow switch drops all IP fragments
+ * before they reach the flow table, so every packet that is available
+ * for matching will have value 0 in this field.
+ *
+ * - Open vSwitch does not implement OFPC_FRAG_REASM mode, but if it did
+ * then IP fragments would be reassembled before they reached the flow
+ * table and again every packet available for matching would always
+ * have value 0.
+ *
+ * - In OFPC_FRAG_NORMAL mode, all three values are possible, but
+ * OpenFlow 1.0 says that fragments' transport ports are always 0, even
+ * for the first fragment, so this does not provide much extra
+ * information.
+ *
+ * - In OFPC_FRAG_NX_MATCH mode, all three values are possible. For
+ * fragments with offset 0, Open vSwitch makes L4 header information
+ * available.
+ *
+ * Type: u8 (low 2 bits).
+ * Maskable: bitwise.
+ * Formatting: frag.
+ * Prerequisites: IPv4/IPv6.
+ * Access: read-only.
+ * NXM: NXM_NX_IP_FRAG(26) since v1.3.
+ * OXM: none.
+ */
+ MFF_IP_FRAG,
+
+/* ## --- ## */
+/* ## ARP ## */
+/* ## --- ## */
+
+ /* "arp_op".
+ *
+ * ARP opcode.
+ *
+ * For an Ethernet+IP ARP packet, the opcode in the ARP header. Always 0
+ * otherwise. Only ARP opcodes between 1 and 255 should be specified for
+ * matching.
+ *
+ * Type: be16.
+ * Maskable: no.
+ * Formatting: decimal.
+ * Prerequisites: ARP.
+ * Access: read/write.
+ * NXM: NXM_OF_ARP_OP(15) since v1.1.
+ * OXM: OXM_OF_ARP_OP(21) since OF1.2 and v1.7.
+ * OF1.0: exact match.
+ * OF1.1: exact match.
+ */
+ MFF_ARP_OP,
+
+ /* "arp_spa".
+ *
+ * For an Ethernet+IP ARP packet, the source protocol (IPv4) address in the
+ * ARP header. Always 0 otherwise.
+ *
+ * Before Open vSwitch 1.8, only CIDR masks were supported.
+ *
+ * Type: be32.
+ * Maskable: bitwise.
+ * Formatting: IPv4.
+ * Prerequisites: ARP.
+ * Access: read/write.
+ * NXM: NXM_OF_ARP_SPA(16) since v1.1.
+ * OXM: OXM_OF_ARP_SPA(22) since OF1.2 and v1.7.
+ * OF1.0: CIDR mask.
+ * OF1.1: bitwise mask.
+ */
+ MFF_ARP_SPA,
+
+ /* "arp_tpa".
+ *
+ * For an Ethernet+IP ARP packet, the target protocol (IPv4) address in the
+ * ARP header. Always 0 otherwise.
+ *
+ * Before Open vSwitch 1.8, only CIDR masks were supported.
+ *
+ * Type: be32.
+ * Maskable: bitwise.
+ * Formatting: IPv4.
+ * Prerequisites: ARP.
+ * Access: read/write.
+ * NXM: NXM_OF_ARP_TPA(17) since v1.1.
+ * OXM: OXM_OF_ARP_TPA(23) since OF1.2 and v1.7.
+ * OF1.0: CIDR mask.
+ * OF1.1: bitwise mask.
+ */
+ MFF_ARP_TPA,
+
+ /* "arp_sha".
+ *
+ * For an Ethernet+IP ARP packet, the source hardware (Ethernet) address in
+ * the ARP header. Always 0 otherwise.
+ *
+ * Type: MAC.
+ * Maskable: bitwise.
+ * Formatting: Ethernet.
+ * Prerequisites: ARP.
+ * Access: read/write.
+ * NXM: NXM_NX_ARP_SHA(17) since v1.1.
+ * OXM: OXM_OF_ARP_SHA(24) since OF1.2 and v1.7.
+ */
+ MFF_ARP_SHA,
+
+ /* "arp_tha".
+ *
+ * For an Ethernet+IP ARP packet, the target hardware (Ethernet) address in
+ * the ARP header. Always 0 otherwise.
+ *
+ * Type: MAC.
+ * Maskable: bitwise.
+ * Formatting: Ethernet.
+ * Prerequisites: ARP.
+ * Access: read/write.
+ * NXM: NXM_NX_ARP_THA(18) since v1.1.
+ * OXM: OXM_OF_ARP_THA(25) since OF1.2 and v1.7.
+ */
+ MFF_ARP_THA,
+
+/* ## --- ## */
+/* ## TCP ## */
+/* ## --- ## */
+
+ /* "tcp_src" (aka "tp_src").
+ *
+ * TCP source port.
+ *
+ * Type: be16.
+ * Maskable: bitwise.
+ * Formatting: decimal.
+ * Prerequisites: TCP.
+ * Access: read/write.
+ * NXM: NXM_OF_TCP_SRC(9) since v1.1.
+ * OXM: OXM_OF_TCP_SRC(13) since OF1.2 and v1.7.
+ * OF1.0: exact match.
+ * OF1.1: exact match.
+ */
+ MFF_TCP_SRC,
+
+ /* "tcp_dst" (aka "tp_dst").
+ *
+ * TCP destination port.
+ *
+ * Type: be16.
+ * Maskable: bitwise.
+ * Formatting: decimal.
+ * Prerequisites: TCP.
+ * Access: read/write.
+ * NXM: NXM_OF_TCP_DST(10) since v1.1.
+ * OXM: OXM_OF_TCP_DST(14) since OF1.2 and v1.7.
+ * OF1.0: exact match.
+ * OF1.1: exact match.
+ */
+ MFF_TCP_DST,
+
+ /* "tcp_flags".
+ *
+ * Flags in the TCP header.
+ *
+ * TCP currently defines 9 flag bits, and additional 3 bits are reserved
+ * (must be transmitted as zero). See RFCs 793, 3168, and 3540.
+ *
+ * Type: be16 (low 12 bits).
+ * Maskable: bitwise.
+ * Formatting: TCP flags.
+ * Prerequisites: TCP.
+ * Access: read-only.
+ * NXM: NXM_NX_TCP_FLAGS(34) since v2.1.
+ * OXM: OXM_OF_TCP_FLAGS(42) since OF1.5 and v2.3.
+ */
+ MFF_TCP_FLAGS,
+
+/* ## --- ## */
+/* ## UDP ## */
+/* ## --- ## */
+
+ /* "udp_src".
+ *
+ * UDP source port.
+ *
+ * Type: be16.
+ * Maskable: bitwise.
+ * Formatting: decimal.
+ * Prerequisites: UDP.
+ * Access: read/write.
+ * NXM: NXM_OF_UDP_SRC(11) since v1.1.
+ * OXM: OXM_OF_UDP_SRC(15) since OF1.2 and v1.7.
+ * OF1.0: exact match.
+ * OF1.1: exact match.
+ */
+ MFF_UDP_SRC,
+
+ /* "udp_dst".
+ *
+ * UDP destination port
+ *
+ * Type: be16.
+ * Maskable: bitwise.
+ * Formatting: decimal.
+ * Prerequisites: UDP.
+ * Access: read/write.
+ * NXM: NXM_OF_UDP_DST(12) since v1.1.
+ * OXM: OXM_OF_UDP_DST(16) since OF1.2 and v1.7.
+ * OF1.0: exact match.
+ * OF1.1: exact match.
+ */
+ MFF_UDP_DST,
+
+/* ## ---- ## */
+/* ## SCTP ## */
+/* ## ---- ## */
+
+ /* "sctp_src".
+ *
+ * SCTP source port.
+ *
+ * Type: be16.
+ * Maskable: bitwise.
+ * Formatting: decimal.
+ * Prerequisites: SCTP.
+ * Access: read/write.
+ * NXM: none.
+ * OXM: OXM_OF_SCTP_SRC(17) since OF1.2 and v2.0.
+ * OF1.1: exact match.
+ */
+ MFF_SCTP_SRC,
+
+ /* "sctp_dst".
+ *
+ * SCTP destination port.
+ *
+ * Type: be16.
+ * Maskable: bitwise.
+ * Formatting: decimal.
+ * Prerequisites: SCTP.
+ * Access: read/write.
+ * NXM: none.
+ * OXM: OXM_OF_SCTP_DST(18) since OF1.2 and v2.0.
+ * OF1.1: exact match.
+ */
+ MFF_SCTP_DST,
+
+/* ## ---- ## */
+/* ## ICMP ## */
+/* ## ---- ## */
+
+ /* "icmp_type".
+ *
+ * ICMPv4 type.
+ *
+ * Type: u8.
+ * Maskable: no.
+ * Formatting: decimal.
+ * Prerequisites: ICMPv4.
+ * Access: read-only.
+ * NXM: NXM_OF_ICMP_TYPE(13) since v1.1.
+ * OXM: OXM_OF_ICMPV4_TYPE(19) since OF1.2 and v1.7.
+ * OF1.0: exact match.
+ * OF1.1: exact match.
+ */
+ MFF_ICMPV4_TYPE,
+
+ /* "icmp_code".
+ *
+ * ICMPv4 code.
+ *
+ * Type: u8.
+ * Maskable: no.
+ * Formatting: decimal.
+ * Prerequisites: ICMPv4.
+ * Access: read-only.
+ * NXM: NXM_OF_ICMP_CODE(14) since v1.1.
+ * OXM: OXM_OF_ICMPV4_CODE(20) since OF1.2 and v1.7.
+ * OF1.0: exact match.
+ * OF1.1: exact match.
+ */
+ MFF_ICMPV4_CODE,
+
+ /* "icmpv6_type".
+ *
+ * ICMPv6 type.
+ *
+ * Type: u8.
+ * Maskable: no.
+ * Formatting: decimal.
+ * Prerequisites: ICMPv6.
+ * Access: read-only.
+ * NXM: NXM_NX_ICMPV6_TYPE(21) since v1.1.
+ * OXM: OXM_OF_ICMPV6_TYPE(29) since OF1.2 and v1.7.
+ */
+ MFF_ICMPV6_TYPE,
+
+ /* "icmpv6_code".
+ *
+ * ICMPv6 code.
+ *
+ * Type: u8.
+ * Maskable: no.
+ * Formatting: decimal.
+ * Prerequisites: ICMPv6.
+ * Access: read-only.
+ * NXM: NXM_NX_ICMPV6_CODE(22) since v1.1.
+ * OXM: OXM_OF_ICMPV6_CODE(30) since OF1.2 and v1.7.
+ */
+ MFF_ICMPV6_CODE,
+
+/* ## ------------------------- ## */
+/* ## ICMPv6 Neighbor Discovery ## */
+/* ## ------------------------- ## */
+
+ /* "nd_target".
+ *
+ * The target address in an IPv6 Neighbor Discovery message.
+ *
+ * Before Open vSwitch 1.8, only CIDR masks were supported.
+ *
+ * Type: IPv6.
+ * Maskable: bitwise.
+ * Formatting: IPv6.
+ * Prerequisites: ND.
+ * Access: read-only.
+ * NXM: NXM_NX_ND_TARGET(23) since v1.1.
+ * OXM: OXM_OF_IPV6_ND_TARGET(31) since OF1.2 and v1.7.
+ */
+ MFF_ND_TARGET,
+
+ /* "nd_sll".
+ *
+ * The source link layer address in an IPv6 Neighbor Discovery message.
+ *
+ * Type: MAC.
+ * Maskable: bitwise.
+ * Formatting: Ethernet.
+ * Prerequisites: ND solicit.
+ * Access: read-only.
+ * NXM: NXM_NX_ND_SLL(24) since v1.1.
+ * OXM: OXM_OF_IPV6_ND_SLL(32) since OF1.2 and v1.7.
+ */
+ MFF_ND_SLL,
+
+ /* "nd_tll".
+ *
+ * The target link layer address in an IPv6 Neighbor Discovery message.
+ *
+ * Type: MAC.
+ * Maskable: bitwise.
+ * Formatting: Ethernet.
+ * Prerequisites: ND advert.
+ * Access: read-only.
+ * NXM: NXM_NX_ND_TLL(25) since v1.1.
+ * OXM: OXM_OF_IPV6_ND_TLL(33) since OF1.2 and v1.7.
+ */
+ MFF_ND_TLL,
MFF_N_IDS
};
MFS_ETHERNET,
MFS_IPV4,
MFS_IPV6,
- MFS_OFP_PORT, /* An OpenFlow port number or name. */
- MFS_OFP_PORT_OXM, /* An OpenFlow port number or name (32-bit). */
+ MFS_OFP_PORT, /* 16-bit OpenFlow 1.0 port number or name. */
+ MFS_OFP_PORT_OXM, /* 32-bit OpenFlow 1.1+ port number or name. */
MFS_FRAG, /* no, yes, first, later, not_later */
MFS_TNL_FLAGS, /* FLOW_TNL_F_* flags */
MFS_TCP_FLAGS, /* TCP_* flags */
* These are combinations of OFPUTIL_P_*. (They are not declared as type
* enum ofputil_protocol because that would give meta-flow.h and ofp-util.h
* a circular dependency.) */
- uint32_t usable_protocols; /* If fully/CIDR masked. */
- uint32_t usable_protocols_bitwise; /* If partially/non-CIDR masked. */
+ uint32_t usable_protocols_exact; /* Matching or setting whole field. */
+ uint32_t usable_protocols_cidr; /* Matching a CIDR mask in field. */
+ uint32_t usable_protocols_bitwise; /* Matching arbitrary bits in field. */
int flow_be32ofs; /* Field's be32 offset in "struct flow", if prefix tree
* lookup is supported for the field, or -1. */
return xasprintf("%s is not a valid value for field %s", value, key);
}
- *usable_protocols &= mf->usable_protocols;
+ *usable_protocols &= mf->usable_protocols_exact;
return NULL;
}