Commit 50fb7992 authored by Tom Herbert's avatar Tom Herbert Committed by David S. Miller

net: Add skb_get_hash_perturb

This calls flow_disect and __skb_get_hash to procure a hash for a
packet. Input includes a key to initialize jhash. This function
does not set skb->hash.
Signed-off-by: default avatarTom Herbert <tom@herbertland.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 6a211654
...@@ -927,6 +927,8 @@ static inline __u32 skb_get_hash(struct sk_buff *skb) ...@@ -927,6 +927,8 @@ static inline __u32 skb_get_hash(struct sk_buff *skb)
return skb->hash; return skb->hash;
} }
__u32 skb_get_hash_perturb(const struct sk_buff *skb, u32 perturb);
static inline __u32 skb_get_hash_raw(const struct sk_buff *skb) static inline __u32 skb_get_hash_raw(const struct sk_buff *skb)
{ {
return skb->hash; return skb->hash;
......
...@@ -267,13 +267,12 @@ static __always_inline void __flow_hash_secret_init(void) ...@@ -267,13 +267,12 @@ static __always_inline void __flow_hash_secret_init(void)
net_get_random_once(&hashrnd, sizeof(hashrnd)); net_get_random_once(&hashrnd, sizeof(hashrnd));
} }
static __always_inline u32 __flow_hash_3words(u32 a, u32 b, u32 c) static __always_inline u32 __flow_hash_3words(u32 a, u32 b, u32 c, u32 keyval)
{ {
__flow_hash_secret_init(); return jhash_3words(a, b, c, keyval);
return jhash_3words(a, b, c, hashrnd);
} }
static inline u32 __flow_hash_from_keys(struct flow_keys *keys) static inline u32 __flow_hash_from_keys(struct flow_keys *keys, u32 keyval)
{ {
u32 hash; u32 hash;
...@@ -287,7 +286,8 @@ static inline u32 __flow_hash_from_keys(struct flow_keys *keys) ...@@ -287,7 +286,8 @@ static inline u32 __flow_hash_from_keys(struct flow_keys *keys)
hash = __flow_hash_3words((__force u32)keys->dst, hash = __flow_hash_3words((__force u32)keys->dst,
(__force u32)keys->src, (__force u32)keys->src,
(__force u32)keys->ports); (__force u32)keys->ports,
keyval);
if (!hash) if (!hash)
hash = 1; hash = 1;
...@@ -296,10 +296,20 @@ static inline u32 __flow_hash_from_keys(struct flow_keys *keys) ...@@ -296,10 +296,20 @@ static inline u32 __flow_hash_from_keys(struct flow_keys *keys)
u32 flow_hash_from_keys(struct flow_keys *keys) u32 flow_hash_from_keys(struct flow_keys *keys)
{ {
return __flow_hash_from_keys(keys); __flow_hash_secret_init();
return __flow_hash_from_keys(keys, hashrnd);
} }
EXPORT_SYMBOL(flow_hash_from_keys); EXPORT_SYMBOL(flow_hash_from_keys);
static inline u32 ___skb_get_hash(const struct sk_buff *skb,
struct flow_keys *keys, u32 keyval)
{
if (!skb_flow_dissect(skb, keys))
return 0;
return __flow_hash_from_keys(keys, keyval);
}
/* /*
* __skb_get_hash: calculate a flow hash based on src/dst addresses * __skb_get_hash: calculate a flow hash based on src/dst addresses
* and src/dst port numbers. Sets hash in skb to non-zero hash value * and src/dst port numbers. Sets hash in skb to non-zero hash value
...@@ -309,8 +319,12 @@ EXPORT_SYMBOL(flow_hash_from_keys); ...@@ -309,8 +319,12 @@ EXPORT_SYMBOL(flow_hash_from_keys);
void __skb_get_hash(struct sk_buff *skb) void __skb_get_hash(struct sk_buff *skb)
{ {
struct flow_keys keys; struct flow_keys keys;
u32 hash;
if (!skb_flow_dissect(skb, &keys)) __flow_hash_secret_init();
hash = ___skb_get_hash(skb, &keys, hashrnd);
if (!hash)
return; return;
if (keys.ports) if (keys.ports)
...@@ -318,10 +332,18 @@ void __skb_get_hash(struct sk_buff *skb) ...@@ -318,10 +332,18 @@ void __skb_get_hash(struct sk_buff *skb)
skb->sw_hash = 1; skb->sw_hash = 1;
skb->hash = __flow_hash_from_keys(&keys); skb->hash = hash;
} }
EXPORT_SYMBOL(__skb_get_hash); EXPORT_SYMBOL(__skb_get_hash);
__u32 skb_get_hash_perturb(const struct sk_buff *skb, u32 perturb)
{
struct flow_keys keys;
return ___skb_get_hash(skb, &keys, perturb);
}
EXPORT_SYMBOL(skb_get_hash_perturb);
/* /*
* Returns a Tx hash based on the given packet descriptor a Tx queues' number * Returns a Tx hash based on the given packet descriptor a Tx queues' number
* to be used as a distribution range. * to be used as a distribution range.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment