Skip to content

Commit 5ed20a6

Browse files
Tom Herbertdavem330
authored andcommitted
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: Tom Herbert <therbert@google.com> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent 081a20f commit 5ed20a6

File tree

2 files changed

+29
-16
lines changed

2 files changed

+29
-16
lines changed

include/net/flow_keys.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,4 +29,5 @@ struct flow_keys {
2929

3030
bool skb_flow_dissect(const struct sk_buff *skb, struct flow_keys *flow);
3131
__be32 skb_flow_get_ports(const struct sk_buff *skb, int thoff, u8 ip_proto);
32+
u32 flow_hash_from_keys(struct flow_keys *keys);
3233
#endif

net/core/flow_dissector.c

Lines changed: 28 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,33 @@ static __always_inline u32 __flow_hash_1word(u32 a)
202202
return jhash_1word(a, hashrnd);
203203
}
204204

205+
static inline u32 __flow_hash_from_keys(struct flow_keys *keys)
206+
{
207+
u32 hash;
208+
209+
/* get a consistent hash (same value on both flow directions) */
210+
if (((__force u32)keys->dst < (__force u32)keys->src) ||
211+
(((__force u32)keys->dst == (__force u32)keys->src) &&
212+
((__force u16)keys->port16[1] < (__force u16)keys->port16[0]))) {
213+
swap(keys->dst, keys->src);
214+
swap(keys->port16[0], keys->port16[1]);
215+
}
216+
217+
hash = __flow_hash_3words((__force u32)keys->dst,
218+
(__force u32)keys->src,
219+
(__force u32)keys->ports);
220+
if (!hash)
221+
hash = 1;
222+
223+
return hash;
224+
}
225+
226+
u32 flow_hash_from_keys(struct flow_keys *keys)
227+
{
228+
return __flow_hash_from_keys(keys);
229+
}
230+
EXPORT_SYMBOL(flow_hash_from_keys);
231+
205232
/*
206233
* __skb_get_hash: calculate a flow hash based on src/dst addresses
207234
* and src/dst port numbers. Sets hash in skb to non-zero hash value
@@ -211,29 +238,14 @@ static __always_inline u32 __flow_hash_1word(u32 a)
211238
void __skb_get_hash(struct sk_buff *skb)
212239
{
213240
struct flow_keys keys;
214-
u32 hash;
215241

216242
if (!skb_flow_dissect(skb, &keys))
217243
return;
218244

219245
if (keys.ports)
220246
skb->l4_hash = 1;
221247

222-
/* get a consistent hash (same value on both flow directions) */
223-
if (((__force u32)keys.dst < (__force u32)keys.src) ||
224-
(((__force u32)keys.dst == (__force u32)keys.src) &&
225-
((__force u16)keys.port16[1] < (__force u16)keys.port16[0]))) {
226-
swap(keys.dst, keys.src);
227-
swap(keys.port16[0], keys.port16[1]);
228-
}
229-
230-
hash = __flow_hash_3words((__force u32)keys.dst,
231-
(__force u32)keys.src,
232-
(__force u32)keys.ports);
233-
if (!hash)
234-
hash = 1;
235-
236-
skb->hash = hash;
248+
skb->hash = __flow_hash_from_keys(&keys);
237249
}
238250
EXPORT_SYMBOL(__skb_get_hash);
239251

0 commit comments

Comments
 (0)