+/* Tunnel matches.
+ *
+ * This module maps packets received over tunnel protocols to vports. The
+ * tunnel protocol and, for some protocols, tunnel-specific information (e.g.,
+ * for VXLAN, the UDP destination port number) are always use as part of the
+ * mapping. Which other fields are used for the mapping depends on the vports
+ * themselves (the parenthesized notations refer to "struct tnl_match" fields):
+ *
+ * - in_key: A vport may match a specific tunnel ID (in_key_flow == false)
+ * or arrange for the tunnel ID to be matched as tunnel.tun_id in the
+ * OpenFlow flow (in_key_flow == true).
+ *
+ * - ip_dst: A vport may match a specific destination IP address
+ * (ip_dst_flow == false) or arrange for the destination IP to be matched
+ * as tunnel.ip_dst in the OpenFlow flow (ip_dst_flow == true).
+ *
+ * - ip_src: A vport may match a specific IP source address (ip_src_flow ==
+ * false, ip_src != 0), wildcard all source addresses (ip_src_flow ==
+ * false, ip_src == 0), or arrange for the IP source address to be
+ * handled in the OpenFlow flow table (ip_src_flow == true).
+ *
+ * Thus, there are 2 * 2 * 3 == 12 possible ways a vport can match against a
+ * tunnel packet. We number the possibilities for each field in increasing
+ * order as listed in each bullet above. We order the 12 overall combinations
+ * in lexicographic order considering in_key first, then ip_dst, then
+ * ip_src. */
+#define N_MATCH_TYPES (2 * 2 * 3)
+
+/* The three possibilities (see above) for vport ip_src matches. */
+enum ip_src_type {
+ IP_SRC_CFG, /* ip_src must equal configured address. */
+ IP_SRC_ANY, /* Any ip_src is acceptable. */
+ IP_SRC_FLOW /* ip_src is handled in flow table. */
+};
+
+/* Each hmap contains "struct tnl_port"s.
+ * The index is a combination of how each of the fields listed under "Tunnel
+ * matches" above matches, see the final paragraph for ordering. */
+static struct hmap *tnl_match_maps[N_MATCH_TYPES] OVS_GUARDED_BY(rwlock);
+static struct hmap **tnl_match_map(const struct tnl_match *);