[dpdk-dev] [PATCH v2 1/4] Link Bonding Library

Stephen Hemminger stephen at networkplumber.org
Thu Jun 5 17:15:57 CEST 2014


On Wed,  4 Jun 2014 16:18:02 +0100
declan.doherty at intel.com wrote:

> From: Declan Doherty <declan.doherty at intel.com>
> 
> - Broadcast TX burst broadcast bug fix
> - Add/remove slave behavior fix
> - Checkpatch fixes
> 
> Signed-off-by: Declan Doherty <declan.doherty at intel.com>

There are some pretty weak hash functions in there.

What about using:

--- a/lib/librte_eal/common/include/rte_common.h	2014-02-27 09:02:23.424698279 -0800
+++ b/lib/librte_eal/common/include/rte_common.h	2014-06-05 08:03:51.615839548 -0700
@@ -365,6 +365,31 @@ rte_str_to_size(const char *str)
 }
 
 /**
+ * Multiplicative hash functions useful to distrbute
+ * a uniform set of consective keys
+ *
+ * @param val
+ *	The input uniform key
+ * @param bits
+ *	Number of bits desired
+ */
+#define GOLDEN_RATIO_32      2654404609U
+static inline uint32_t
+rte_fib_hash32(uint32_t val, unsigned int bits)
+{
+	val *= GOLDEN_RATIO_32;
+	return val >> (32 - bits);
+}
+
+#define	GOLDEN_RATIO_64	0x9e37fffffffc0001UL
+static inline uint64_t
+rte_fib_hash64(uint64_t val, unsigned bits)
+{
+	val *= GOLDEN_RATIO_64;
+	return val >> (64 - bits);
+}
+
+/**
  * Function to terminate the application immediately, printing an error
  * message and returning the exit_code back to the shell.
  *
--- a/lib/librte_ether/rte_ether.h	2014-02-27 09:02:23.438697987 -0800
+++ b/lib/librte_ether/rte_ether.h	2014-06-05 08:14:15.438080058 -0700
@@ -48,6 +48,8 @@ extern "C" {
 
 #include <rte_memcpy.h>
 #include <rte_random.h>
+#include <rte_common.h>
+#include <rte_jhash.h>
 
 #define ETHER_ADDR_LEN  6 /**< Length of Ethernet address. */
 #define ETHER_TYPE_LEN  2 /**< Length of Ethernet type field. */
@@ -250,6 +252,80 @@ struct ether_hdr {
 	uint16_t ether_type;      /**< Frame type. */
 } __attribute__((__packed__));
 
+
+/*
+ * These functions work by aliasing the 6 byte Ethernet address
+ * into a 64 bit value. The macro shift16, removes the extra
+ * bytes with the correct shift depending on byte order
+ */
+#ifdef __BYTE_ORDER
+  #if __BYTE_ORDER == __BIG_ENDIAN
+    #define shift16(s) (s >>= 16)
+  #else
+    #define shift16(s) (s <<= 16)
+  #endif
+#endif
+
+/**
+ * Fast compare of  Ethernet address.
+ *
+ * @param e1
+ *   A pointer to a ether_addr structure one address
+ * @param e2
+ *   A pointer to a ether_addr structure holding other address
+ * @return
+ *   True  (1) if addresses are the same
+ *   false (0) otherwise.
+ */
+static inline int
+ether_addr_equal(const struct ether_addr *e1, const struct ether_addr *e2)
+{
+	uint64_t e1_addr = *(const uint64_t *) e1;
+	shift16(e1_addr);
+	uint64_t e2_addr = *(const uint64_t *) e2;
+	shift16(e2_addr);
+
+	return (e1_addr == e2_addr);
+}
+
+/**
+ * Fast hash of ethernet address
+ *
+ * @param ea
+ *   A pointer to a ether_addr structure
+ * @param bits
+ *   Number of bits desired
+ * @return
+ *   Calculated hash value.
+ */
+static inline uint32_t
+ether_addr_hash(const struct ether_addr *ea, unsigned bits)
+{
+	uint64_t val = *(const uint64_t *) ea;
+
+	shift16(val);
+	return rte_fib_hash64(val, bits);
+}
+#undef shift16
+
+/**
+ * Hash of ethernet source and destination
+ *
+ * @param ea
+ *   A pointer to a ether_hdr structure
+ * @param initval
+ *   Initialising value of hash.
+ * @return
+ *   Calculated hash value.
+ */
+static inline uint32_t
+ether_header_hash(const struct ether_hdr *hdr, unsigned seed)
+{
+	const uint32_t *key = (const uint32_t *)hdr;
+
+	return rte_jhash(key, 2*ETHER_ADDR_LEN, seed);
+}
+
 /**
  * Ethernet VLAN Header.
  * Contains the 16-bit VLAN Tag Control Identifier and the Ethernet type


More information about the dev mailing list