提交 5ed20a68 编写于 作者: T Tom Herbert 提交者: David S. Miller

flow_dissector: Abstract out hash computation

Move the hash computation located in __skb_get_hash to be a separate
function which takes flow_keys as input. This will allow flow hash
computation in other contexts where we only have addresses and ports.
Signed-off-by: NTom Herbert <therbert@google.com>
Signed-off-by: NDavid S. Miller <davem@davemloft.net>
上级 081a20ff
...@@ -29,4 +29,5 @@ struct flow_keys { ...@@ -29,4 +29,5 @@ struct flow_keys {
bool skb_flow_dissect(const struct sk_buff *skb, struct flow_keys *flow); bool skb_flow_dissect(const struct sk_buff *skb, struct flow_keys *flow);
__be32 skb_flow_get_ports(const struct sk_buff *skb, int thoff, u8 ip_proto); __be32 skb_flow_get_ports(const struct sk_buff *skb, int thoff, u8 ip_proto);
u32 flow_hash_from_keys(struct flow_keys *keys);
#endif #endif
...@@ -202,6 +202,33 @@ static __always_inline u32 __flow_hash_1word(u32 a) ...@@ -202,6 +202,33 @@ static __always_inline u32 __flow_hash_1word(u32 a)
return jhash_1word(a, hashrnd); return jhash_1word(a, hashrnd);
} }
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;
}
u32 flow_hash_from_keys(struct flow_keys *keys)
{
return __flow_hash_from_keys(keys);
}
EXPORT_SYMBOL(flow_hash_from_keys);
/* /*
* __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
...@@ -211,7 +238,6 @@ static __always_inline u32 __flow_hash_1word(u32 a) ...@@ -211,7 +238,6 @@ static __always_inline u32 __flow_hash_1word(u32 a)
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)) if (!skb_flow_dissect(skb, &keys))
return; return;
...@@ -219,21 +245,7 @@ void __skb_get_hash(struct sk_buff *skb) ...@@ -219,21 +245,7 @@ void __skb_get_hash(struct sk_buff *skb)
if (keys.ports) if (keys.ports)
skb->l4_hash = 1; skb->l4_hash = 1;
/* get a consistent hash (same value on both flow directions) */ skb->hash = __flow_hash_from_keys(&keys);
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;
skb->hash = hash;
} }
EXPORT_SYMBOL(__skb_get_hash); EXPORT_SYMBOL(__skb_get_hash);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册