u32 __skb_get_hash(struct sk_buff *skb) { struct flow_keys keys; u32 hash; if (!skb_flow_dissect(skb, &keys)) return 0; /* get a consistent hash (same value on both flow directions) */ if (((__force u32)keys.dst < (__force u32)keys.src) || (((__force u32)keys.dst == (__force u32)keys.src) && ((__force u16)keys.port16[1] < (__force u16)keys.port16[0]))) { swap(keys.dst, keys.src); swap(keys.port16[0], keys.port16[1]); } hash = __flow_hash_3words((__force u32)keys.dst, (__force u32)keys.src, (__force u32)keys.ports); if (!hash) hash = 1; #ifdef HAVE_RXHASH skb->rxhash = hash; #endif return hash; }
static inline u32 __flow_hash_from_keys(struct flow_keys *keys) { u32 hash; /* get a consistent hash (same value on both flow directions) */ if (((__force u32)keys->dst < (__force u32)keys->src) || (((__force u32)keys->dst == (__force u32)keys->src) && ((__force u16)keys->port16[1] < (__force u16)keys->port16[0]))) { swap(keys->dst, keys->src); swap(keys->port16[0], keys->port16[1]); } hash = __flow_hash_3words((__force u32)keys->dst, (__force u32)keys->src, (__force u32)keys->ports); if (!hash) hash = 1; return hash; }