From 520e9a2acdcf6136bf0a20586df6351ecf72dd3e Mon Sep 17 00:00:00 2001 From: Ethan Jackson Date: Wed, 13 Jul 2011 16:20:24 -0700 Subject: [PATCH] nicira-ext: Generalize nx_mp_fields into nx_hash_fields. Future patches will use nx_hash_fields for non-multipath related actions. This patch renames nx_mp_fields and creates a new flow_hash_fields() function. --- include/openflow/nicira-ext.h | 43 +++++++++++++++++------------------ lib/flow.c | 36 +++++++++++++++++++++++++++++ lib/flow.h | 4 ++++ lib/multipath.c | 38 +++++-------------------------- 4 files changed, 67 insertions(+), 54 deletions(-) diff --git a/include/openflow/nicira-ext.h b/include/openflow/nicira-ext.h index d73f3ba8..006d27de 100644 --- a/include/openflow/nicira-ext.h +++ b/include/openflow/nicira-ext.h @@ -167,6 +167,25 @@ enum nicira_stats_type { 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 @@ -498,7 +517,7 @@ OFP_ASSERT(sizeof(struct nx_action_note) == 16); * * 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, @@ -535,7 +554,7 @@ struct nx_action_multipath { 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; @@ -551,26 +570,6 @@ struct nx_action_multipath { }; 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. */ diff --git a/lib/flow.c b/lib/flow.c index e6607bf1..fc09a77a 100644 --- a/lib/flow.c +++ b/lib/flow.c @@ -852,3 +852,39 @@ flow_hash_symmetric_l4(const struct flow *flow, uint32_t basis) } 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 ""; + } +} + +/* 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; +} diff --git a/lib/flow.h b/lib/flow.h index f7a0c23b..ba2d8063 100644 --- a/lib/flow.h +++ b/lib/flow.h @@ -171,5 +171,9 @@ const uint8_t *flow_wildcards_to_dl_dst_mask(flow_wildcards_t); 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 */ diff --git a/lib/multipath.c b/lib/multipath.c index 07e0ada2..4ee6fd02 100644 --- a/lib/multipath.c +++ b/lib/multipath.c @@ -40,8 +40,7 @@ multipath_check(const struct nx_action_multipath *mp) 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) @@ -64,8 +63,6 @@ multipath_check(const struct nx_action_multipath *mp) /* 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); @@ -73,7 +70,8 @@ void 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)); @@ -86,21 +84,6 @@ multipath_execute(const struct nx_action_multipath *mp, struct flow *flow) *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) { @@ -204,9 +187,9 @@ multipath_parse(struct nx_action_multipath *mp, const char *s_) 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); } @@ -253,16 +236,7 @@ multipath_format(const struct nx_action_multipath *mp, struct ds *s) 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 = ""; - } + fields = flow_hash_fields_to_str(mp_fields); switch ((enum nx_mp_algorithm) mp_algorithm) { case NX_MP_ALG_MODULO_N: -- 2.30.2