diff options
author | Tom Herbert <therbert@google.com> | 2015-02-24 12:17:31 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2015-02-27 16:00:01 -0500 |
commit | 723b8e460d87e957f251dc5764f4ab86af6ab44e (patch) | |
tree | 2453607eb05e7cdf3913fedfe55599641c6a66b1 /include/net | |
parent | fed0a159c8c5e453d79d6a73897c576efea0a8a5 (diff) |
udp: In udp_flow_src_port use random hash value if skb_get_hash fails
In the unlikely event that skb_get_hash is unable to deduce a hash
in udp_flow_src_port we use a consistent random value instead.
This is specified in GRE/UDP draft section 3.2.1:
https://tools.ietf.org/html/draft-ietf-tsvwg-gre-in-udp-encap-04
Signed-off-by: Tom Herbert <therbert@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'include/net')
-rw-r--r-- | include/net/udp.h | 21 |
1 files changed, 15 insertions, 6 deletions
diff --git a/include/net/udp.h b/include/net/udp.h index 07f9b70962f6..32d8d9f07f76 100644 --- a/include/net/udp.h +++ b/include/net/udp.h | |||
@@ -194,6 +194,8 @@ int udp_lib_get_port(struct sock *sk, unsigned short snum, | |||
194 | int (*)(const struct sock *, const struct sock *), | 194 | int (*)(const struct sock *, const struct sock *), |
195 | unsigned int hash2_nulladdr); | 195 | unsigned int hash2_nulladdr); |
196 | 196 | ||
197 | u32 udp_flow_hashrnd(void); | ||
198 | |||
197 | static inline __be16 udp_flow_src_port(struct net *net, struct sk_buff *skb, | 199 | static inline __be16 udp_flow_src_port(struct net *net, struct sk_buff *skb, |
198 | int min, int max, bool use_eth) | 200 | int min, int max, bool use_eth) |
199 | { | 201 | { |
@@ -205,12 +207,19 @@ static inline __be16 udp_flow_src_port(struct net *net, struct sk_buff *skb, | |||
205 | } | 207 | } |
206 | 208 | ||
207 | hash = skb_get_hash(skb); | 209 | hash = skb_get_hash(skb); |
208 | if (unlikely(!hash) && use_eth) { | 210 | if (unlikely(!hash)) { |
209 | /* Can't find a normal hash, caller has indicated an Ethernet | 211 | if (use_eth) { |
210 | * packet so use that to compute a hash. | 212 | /* Can't find a normal hash, caller has indicated an |
211 | */ | 213 | * Ethernet packet so use that to compute a hash. |
212 | hash = jhash(skb->data, 2 * ETH_ALEN, | 214 | */ |
213 | (__force u32) skb->protocol); | 215 | hash = jhash(skb->data, 2 * ETH_ALEN, |
216 | (__force u32) skb->protocol); | ||
217 | } else { | ||
218 | /* Can't derive any sort of hash for the packet, set | ||
219 | * to some consistent random value. | ||
220 | */ | ||
221 | hash = udp_flow_hashrnd(); | ||
222 | } | ||
214 | } | 223 | } |
215 | 224 | ||
216 | /* Since this is being sent on the wire obfuscate hash a bit | 225 | /* Since this is being sent on the wire obfuscate hash a bit |