diff --git a/build-aux/extract-ofp-fields b/build-aux/extract-ofp-fields new file mode 100755 index 000000000..554364704 --- /dev/null +++ b/build-aux/extract-ofp-fields @@ -0,0 +1,458 @@ +#! /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 '' 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 within the comment, + # and drop lines that have for x != n. + instance = [] + for x in comment: + y = x.replace('', 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 + diff --git a/include/openflow/nicira-ext.h b/include/openflow/nicira-ext.h index bbf3388fa..b1885b276 100644 --- a/include/openflow/nicira-ext.h +++ b/include/openflow/nicira-ext.h @@ -482,406 +482,13 @@ OFP_ASSERT(sizeof(struct nx_async_config) == 24); #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 @@ -898,75 +505,6 @@ OFP_ASSERT(sizeof(struct nx_async_config) == 24); #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. ## */ diff --git a/include/openflow/openflow-1.2.h b/include/openflow/openflow-1.2.h index 58be0b57b..ef1d340ec 100644 --- a/include/openflow/openflow-1.2.h +++ b/include/openflow/openflow-1.2.h @@ -72,131 +72,8 @@ enum ofp12_oxm_class { 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. */ diff --git a/lib/automake.mk b/lib/automake.mk index 6c1db9a7e..329eca7b8 100644 --- a/lib/automake.mk +++ b/lib/automake.mk @@ -443,13 +443,19 @@ lib/dirs.c: lib/dirs.c.in Makefile > 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 \ diff --git a/lib/meta-flow.c b/lib/meta-flow.c index aa48a1671..b59aae7d9 100644 --- a/lib/meta-flow.c +++ b/lib/meta-flow.c @@ -47,755 +47,7 @@ VLOG_DEFINE_THIS_MODULE(meta_flow); 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. */ @@ -2132,7 +1384,7 @@ mf_set(const struct mf_field *mf, { 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; @@ -2231,11 +1483,11 @@ mf_set(const struct mf_field *mf, 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); @@ -2263,11 +1515,11 @@ mf_set(const struct mf_field *mf, 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: @@ -2290,11 +1542,10 @@ mf_set(const struct mf_field *mf, 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 diff --git a/lib/meta-flow.h b/lib/meta-flow.h index c11f7abc4..2dd087a1d 100644 --- a/lib/meta-flow.h +++ b/lib/meta-flow.h @@ -29,116 +29,1310 @@ 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." 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. v." 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 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". + * + * 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". + * + * 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() 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 */ +/* ## -------- ## */ +/* ## Ethernet ## */ +/* ## -------- ## */ - 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: + /* "eth_src" (aka "dl_src"). * - * - 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 + * Source address in Ethernet header. * - * - 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) */ + * 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, - MFF_ARP_OP, /* be16 */ - MFF_ARP_SPA, /* be32 */ - MFF_ARP_TPA, /* be32 */ - MFF_ARP_SHA, /* mac */ - MFF_ARP_THA, /* mac */ + /* "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, - /* 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) */ + /* "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, - MFF_UDP_SRC, /* be16 (used for IPv4 or IPv6) */ - MFF_UDP_DST, /* be16 (used for IPv4 or IPv6) */ +/* ## ---- ## */ +/* ## VLAN ## */ +/* ## ---- ## */ - MFF_SCTP_SRC, /* be16 (used for IPv4 or IPv6) */ - MFF_SCTP_DST, /* be16 (used for IPv4 or IPv6) */ +/* 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. */ - MFF_ICMPV4_TYPE, /* u8 */ - MFF_ICMPV4_CODE, /* u8 */ + /* "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, - MFF_ICMPV6_TYPE, /* u8 */ - MFF_ICMPV6_CODE, /* u8 */ + /* "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, - /* ICMPv6 Neighbor Discovery. */ - MFF_ND_TARGET, /* ipv6 */ - MFF_ND_SLL, /* mac */ - MFF_ND_TLL, /* mac */ + /* "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 }; @@ -220,8 +1414,8 @@ enum OVS_PACKED_ENUM mf_string { 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 */ @@ -299,8 +1493,9 @@ struct mf_field { * 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. */ diff --git a/lib/ofp-actions.c b/lib/ofp-actions.c index 219f492fc..39c5a29b5 100644 --- a/lib/ofp-actions.c +++ b/lib/ofp-actions.c @@ -2232,7 +2232,7 @@ set_field_parse__(char *arg, struct ofpbuf *ofpacts, 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; }