NXST_AGGREGATE /* Analogous to OFPST_AGGREGATE. */
};
+/* Fields to use when hashing flows. */
+enum nx_hash_fields {
+ /* Ethernet source address (NXM_OF_ETH_SRC) only. */
+ NX_HASH_FIELDS_ETH_SRC,
+
+ /* L2 through L4, symmetric across src/dst. Specifically, each of the
+ * following fields, if present, is hashed (slashes separate symmetric
+ * pairs):
+ *
+ * - NXM_OF_ETH_DST / NXM_OF_ETH_SRC
+ * - NXM_OF_ETH_TYPE
+ * - The VID bits from NXM_OF_VLAN_TCI, ignoring PCP and CFI.
+ * - NXM_OF_IP_PROTO
+ * - NXM_OF_IP_SRC / NXM_OF_IP_DST
+ * - NXM_OF_TCP_SRC / NXM_OF_TCP_DST
+ */
+ NX_HASH_FIELDS_SYMMETRIC_L4
+};
+
/* This command enables or disables an Open vSwitch extension that allows a
* controller to specify the OpenFlow table to which a flow should be added,
* instead of having the switch decide which table is most appropriate as
*
* This action performs the following steps in sequence:
*
- * 1. Hashes the fields designated by 'fields', one of NX_MP_FIELDS_*.
+ * 1. Hashes the fields designated by 'fields', one of NX_HASH_FIELDS_*.
* Refer to the definition of "enum nx_mp_fields" for details.
*
* The 'basis' value is used as a universal hash parameter, that is,
ovs_be16 subtype; /* NXAST_MULTIPATH. */
/* What fields to hash and how. */
- ovs_be16 fields; /* One of NX_MP_FIELDS_*. */
+ ovs_be16 fields; /* One of NX_HASH_FIELDS_*. */
ovs_be16 basis; /* Universal hash parameter. */
ovs_be16 pad0;
};
OFP_ASSERT(sizeof(struct nx_action_multipath) == 32);
-/* NXAST_MULTIPATH: Fields to hash. */
-enum nx_mp_fields {
- /* Ethernet source address (NXM_OF_ETH_SRC) only. */
- NX_MP_FIELDS_ETH_SRC,
-
- /* L2 through L4, symmetric across src/dst. Specifically, each of the
- * following fields, if present, is hashed (slashes separate symmetric
- * pairs):
- *
- * - NXM_OF_ETH_DST / NXM_OF_ETH_SRC
- * - NXM_OF_ETH_TYPE
- * - The VID bits from NXM_OF_VLAN_TCI, ignoring PCP and CFI.
- * - NXM_OF_IP_PROTO
- * - NXM_OF_IP_SRC / NXM_OF_IP_DST
- * - NXM_OF_TCP_SRC / NXM_OF_TCP_DST
- * - NXM_OF_UDP_SRC / NXM_OF_UDP_DST
- */
- NX_MP_FIELDS_SYMMETRIC_L4
-};
-
/* NXAST_MULTIPATH: Multipath link choice algorithm to apply.
*
* In the descriptions below, 'n_links' is max_link + 1. */
}
return hash_bytes(&fields, sizeof fields, basis);
}
+
+/* Hashes the portions of 'flow' designated by 'fields'. */
+uint32_t
+flow_hash_fields(const struct flow *flow, enum nx_hash_fields fields,
+ uint16_t basis)
+{
+ switch (fields) {
+
+ case NX_HASH_FIELDS_ETH_SRC:
+ return hash_bytes(flow->dl_src, sizeof flow->dl_src, basis);
+
+ case NX_HASH_FIELDS_SYMMETRIC_L4:
+ return flow_hash_symmetric_l4(flow, basis);
+ }
+
+ NOT_REACHED();
+}
+
+/* Returns a string representation of 'fields'. */
+const char *
+flow_hash_fields_to_str(enum nx_hash_fields fields)
+{
+ switch (fields) {
+ case NX_HASH_FIELDS_ETH_SRC: return "eth_src";
+ case NX_HASH_FIELDS_SYMMETRIC_L4: return "symmetric_l4";
+ default: return "<unknown>";
+ }
+}
+
+/* Returns true if the value of 'fields' is supported. Otherwise false. */
+bool
+flow_hash_fields_valid(enum nx_hash_fields fields)
+{
+ return fields == NX_HASH_FIELDS_ETH_SRC
+ || fields == NX_HASH_FIELDS_SYMMETRIC_L4;
+}
bool flow_wildcards_is_dl_dst_mask_valid(const uint8_t[6]);
flow_wildcards_t flow_wildcards_set_dl_dst_mask(flow_wildcards_t,
const uint8_t mask[6]);
+uint32_t flow_hash_fields(const struct flow *, enum nx_hash_fields,
+ uint16_t basis);
+const char *flow_hash_fields_to_str(enum nx_hash_fields);
+bool flow_hash_fields_valid(enum nx_hash_fields);
#endif /* flow.h */
int ofs = nxm_decode_ofs(mp->ofs_nbits);
int n_bits = nxm_decode_n_bits(mp->ofs_nbits);
- if (mp->fields != htons(NX_MP_FIELDS_ETH_SRC)
- && mp->fields != htons(NX_MP_FIELDS_SYMMETRIC_L4)) {
+ if (!flow_hash_fields_valid(ntohs(mp->fields))) {
VLOG_WARN_RL(&rl, "unsupported fields %"PRIu16, ntohs(mp->fields));
} else if (mp->algorithm != htons(NX_MP_ALG_MODULO_N)
&& mp->algorithm != htons(NX_MP_ALG_HASH_THRESHOLD)
\f
/* multipath_execute(). */
-static uint32_t multipath_hash(const struct flow *, enum nx_mp_fields,
- uint16_t basis);
static uint16_t multipath_algorithm(uint32_t hash, enum nx_mp_algorithm,
unsigned int n_links, unsigned int arg);
multipath_execute(const struct nx_action_multipath *mp, struct flow *flow)
{
/* Calculate value to store. */
- uint32_t hash = multipath_hash(flow, ntohs(mp->fields), ntohs(mp->basis));
+ uint32_t hash = flow_hash_fields(flow, ntohs(mp->fields),
+ ntohs(mp->basis));
uint16_t link = multipath_algorithm(hash, ntohs(mp->algorithm),
ntohs(mp->max_link) + 1,
ntohl(mp->arg));
*reg = (*reg & ~(mask << ofs)) | (link << ofs);
}
-static uint32_t
-multipath_hash(const struct flow *flow, enum nx_mp_fields fields,
- uint16_t basis)
-{
- switch (fields) {
- case NX_MP_FIELDS_ETH_SRC:
- return hash_bytes(flow->dl_src, sizeof flow->dl_src, basis);
-
- case NX_MP_FIELDS_SYMMETRIC_L4:
- return flow_hash_symmetric_l4(flow, basis);
- }
-
- NOT_REACHED();
-}
-
static uint16_t
algorithm_hrw(uint32_t hash, unsigned int n_links)
{
mp->vendor = htonl(NX_VENDOR_ID);
mp->subtype = htons(NXAST_MULTIPATH);
if (!strcasecmp(fields, "eth_src")) {
- mp->fields = htons(NX_MP_FIELDS_ETH_SRC);
+ mp->fields = htons(NX_HASH_FIELDS_ETH_SRC);
} else if (!strcasecmp(fields, "symmetric_l4")) {
- mp->fields = htons(NX_MP_FIELDS_SYMMETRIC_L4);
+ mp->fields = htons(NX_HASH_FIELDS_SYMMETRIC_L4);
} else {
ovs_fatal(0, "%s: unknown fields `%s'", s_, fields);
}
uint16_t mp_fields = ntohs(mp->fields);
uint16_t mp_algorithm = ntohs(mp->algorithm);
- switch ((enum nx_mp_fields) mp_fields) {
- case NX_MP_FIELDS_ETH_SRC:
- fields = "eth_src";
- break;
- case NX_MP_FIELDS_SYMMETRIC_L4:
- fields = "symmetric_l4";
- break;
- default:
- fields = "<unknown>";
- }
+ fields = flow_hash_fields_to_str(mp_fields);
switch ((enum nx_mp_algorithm) mp_algorithm) {
case NX_MP_ALG_MODULO_N: