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