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: Tom Herbert <tom@herbertland.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Tom Herbert 2015-05-01 11:30:12 -07:00 committed by David S. Miller
parent 6a21165480
commit 50fb799289
2 changed files with 32 additions and 8 deletions

View file

@ -927,6 +927,8 @@ static inline __u32 skb_get_hash(struct sk_buff *skb)
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)
{
return skb->hash;

View file

@ -267,13 +267,12 @@ static __always_inline void __flow_hash_secret_init(void)
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, hashrnd);
return jhash_3words(a, b, c, keyval);
}
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;
@ -287,7 +286,8 @@ static inline u32 __flow_hash_from_keys(struct flow_keys *keys)
hash = __flow_hash_3words((__force u32)keys->dst,
(__force u32)keys->src,
(__force u32)keys->ports);
(__force u32)keys->ports,
keyval);
if (!hash)
hash = 1;
@ -296,10 +296,20 @@ static inline 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);
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
* and src/dst port numbers. Sets hash in skb to non-zero hash value
@ -309,8 +319,12 @@ EXPORT_SYMBOL(flow_hash_from_keys);
void __skb_get_hash(struct sk_buff *skb)
{
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;
if (keys.ports)
@ -318,10 +332,18 @@ void __skb_get_hash(struct sk_buff *skb)
skb->sw_hash = 1;
skb->hash = __flow_hash_from_keys(&keys);
skb->hash = 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
* to be used as a distribution range.