lib/rstp: Refactor port initialization.
[cascardo/ovs.git] / lib / meta-flow.h
index cf92556..c11f7ab 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2012, 2013 Nicira, Inc.
+ * Copyright (c) 2011, 2012, 2013, 2014 Nicira, Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -20,9 +20,9 @@
 #include <sys/types.h>
 #include <netinet/in.h>
 #include <netinet/ip6.h>
+#include "bitmap.h"
 #include "flow.h"
 #include "ofp-errors.h"
-#include "ofp-util.h"
 #include "packets.h"
 #include "util.h"
 
@@ -33,6 +33,8 @@ struct match;
  * to represent its value. */
 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 */
@@ -45,29 +47,26 @@ enum OVS_PACKED_ENUM mf_field_id {
     MFF_SKB_PRIORITY,           /* be32 */
     MFF_PKT_MARK,               /* be32 */
 
-#if FLOW_N_REGS > 0
+#if FLOW_N_REGS == 8
     MFF_REG0,                   /* be32 */
-#endif
-#if FLOW_N_REGS > 1
     MFF_REG1,                   /* be32 */
-#endif
-#if FLOW_N_REGS > 2
     MFF_REG2,                   /* be32 */
-#endif
-#if FLOW_N_REGS > 3
     MFF_REG3,                   /* be32 */
-#endif
-#if FLOW_N_REGS > 4
     MFF_REG4,                   /* be32 */
-#endif
-#if FLOW_N_REGS > 5
     MFF_REG5,                   /* be32 */
-#endif
-#if FLOW_N_REGS > 6
     MFF_REG6,                   /* be32 */
-#endif
-#if FLOW_N_REGS > 7
     MFF_REG7,                   /* be32 */
+#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 */
+#else
+#error "Need to update MFF_REG* to match FLOW_N_XREGS"
 #endif
 
     /* L2. */
@@ -87,6 +86,8 @@ enum OVS_PACKED_ENUM mf_field_id {
     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 */
 
@@ -142,38 +143,29 @@ enum OVS_PACKED_ENUM mf_field_id {
     MFF_N_IDS
 };
 
+/* A set of mf_field_ids. */
+struct mf_bitmap {
+    unsigned long bm[BITMAP_N_LONGS(MFF_N_IDS)];
+};
+#define MF_BITMAP_INITIALIZER { { [0] = 0 } }
+
 /* Use this macro as CASE_MFF_REGS: in a switch statement to choose all of the
- * MFF_REGx cases. */
-#if FLOW_N_REGS == 1
-# define CASE_MFF_REGS                                          \
-    case MFF_REG0
-#elif FLOW_N_REGS == 2
-# define CASE_MFF_REGS                                          \
-    case MFF_REG0: case MFF_REG1
-#elif FLOW_N_REGS == 3
-# define CASE_MFF_REGS                                          \
-    case MFF_REG0: case MFF_REG1: case MFF_REG2
-#elif FLOW_N_REGS == 4
-# define CASE_MFF_REGS                                          \
-    case MFF_REG0: case MFF_REG1: case MFF_REG2: case MFF_REG3
-#elif FLOW_N_REGS == 5
-# define CASE_MFF_REGS                                          \
-    case MFF_REG0: case MFF_REG1: case MFF_REG2: case MFF_REG3: \
-    case MFF_REG4
-#elif FLOW_N_REGS == 6
-# define CASE_MFF_REGS                                          \
-    case MFF_REG0: case MFF_REG1: case MFF_REG2: case MFF_REG3: \
-    case MFF_REG4: case MFF_REG5
-#elif FLOW_N_REGS == 7
-# define CASE_MFF_REGS                                          \
-    case MFF_REG0: case MFF_REG1: case MFF_REG2: case MFF_REG3: \
-    case MFF_REG4: case MFF_REG5: case MFF_REG6
-#elif FLOW_N_REGS == 8
-# define CASE_MFF_REGS                                          \
+ * MFF_REGn cases. */
+#if FLOW_N_REGS == 8
+#define CASE_MFF_REGS                                           \
     case MFF_REG0: case MFF_REG1: case MFF_REG2: case MFF_REG3: \
     case MFF_REG4: case MFF_REG5: case MFF_REG6: case MFF_REG7
 #else
-# error
+#error "Need to update CASE_MFF_REGS to match FLOW_N_REGS"
+#endif
+
+/* Use this macro as CASE_MFF_XREGS: in a switch statement to choose all of the
+ * MFF_REGn cases. */
+#if FLOW_N_XREGS == 4
+#define CASE_MFF_XREGS                                              \
+    case MFF_XREG0: case MFF_XREG1: case MFF_XREG2: case MFF_XREG3
+#else
+#error "Need to update CASE_MFF_XREGS to match FLOW_N_XREGS"
 #endif
 
 /* Prerequisites for matching a field.
@@ -272,6 +264,11 @@ struct mf_field {
      *
      *   - NXM and OXM both define such a field: nxm_header and oxm_header will
      *     both be nonzero and different, similarly for nxm_name and oxm_name.
+     *     In this case, 'oxm_version' is significant: if it is greater than
+     *     OFP12_VERSION, then only that version of OpenFlow introduced this
+     *     OXM header, so ovs-vswitchd should send 'nxm_header' instead with
+     *     earlier protocol versions to avoid confusing controllers that were
+     *     using a previous Open vSwitch extension.
      *
      *   - Only NXM or only OXM defines such a field: nxm_header and oxm_header
      *     will both have the same value (either an OXM_* or NXM_* value) and
@@ -281,22 +278,29 @@ struct mf_field {
      * NXM formatted match, since it will be an NXM_* constant when possible
      * for compatibility with OpenFlow implementations that expect that, with
      * OXM_* constants used for fields that OXM adds.  Conversely, 'oxm_header'
-     * is the header to use when outputting an OXM formatted match. */
+     * is the header to use when outputting an OXM formatted match to an
+     * OpenFlow connection of version 'oxm_version' or above (and otherwise
+     * 'nxm_header'). */
     uint32_t nxm_header;        /* An NXM_* (or OXM_*) constant. */
     const char *nxm_name;       /* The nxm_header constant's name. */
     uint32_t oxm_header;        /* An OXM_* (or NXM_*) constant. */
     const char *oxm_name;       /* The oxm_header constant's name */
+    enum ofp_version oxm_version; /* OpenFlow version that added oxm_header. */
 
     /* Usable protocols.
+     *
      * NXM and OXM are extensible, allowing later extensions to be sent in
      * earlier protocol versions, so this does not necessarily correspond to
      * the OpenFlow protocol version the field was introduced in.
      * Also, some field types are tranparently mapped to each other via the
      * struct flow (like vlan and dscp/tos fields), so each variant supports
-     * all protocols. */
-    enum ofputil_protocol usable_protocols; /* If fully/cidr masked. */
-    /* If partially/non-cidr masked. */
-    enum ofputil_protocol usable_protocols_bitwise;
+     * all protocols.
+     *
+     * 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. */
 
     int flow_be32ofs;  /* Field's be32 offset in "struct flow", if prefix tree
                         * lookup is supported for the field, or -1. */
@@ -348,6 +352,9 @@ mf_from_id(enum mf_field_id id)
     return &mf_fields[id];
 }
 
+/* NXM and OXM protocol headers. */
+uint32_t mf_oxm_header(enum mf_field_id, enum ofp_version oxm_version);
+
 /* Inspecting wildcarded bits. */
 bool mf_is_all_wild(const struct mf_field *, const struct flow_wildcards *);
 
@@ -359,6 +366,12 @@ void mf_get_mask(const struct mf_field *, const struct flow_wildcards *,
 bool mf_are_prereqs_ok(const struct mf_field *, const struct flow *);
 void mf_mask_field_and_prereqs(const struct mf_field *, struct flow *mask);
 
+static inline bool
+mf_is_l3_or_higher(const struct mf_field *mf)
+{
+    return mf->id >= MFF_IPV4_SRC;
+}
+
 /* Field values. */
 bool mf_is_value_valid(const struct mf_field *, const union mf_value *value);