aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTom Herbert <therbert@google.com>2014-07-02 00:32:39 -0400
committerDavid S. Miller <davem@davemloft.net>2014-07-08 00:14:21 -0400
commitb8f1a55639e6a76cfd274cc7de76eafac9a15ca9 (patch)
treef2c030ea28fc30a42f740b9ac4da0edc32924831
parent0e001614e849b68cff94cda8db8b550569d3dba6 (diff)
udp: Add function to make source port for UDP tunnels
This patch adds udp_flow_src_port function which is intended to be a common function that UDP tunnel implementations call to set the source port. The source port is chosen so that a hash over the outer headers (IP addresses and UDP ports) acts as suitable hash for the flow of the encapsulated packet. In this manner, UDP encapsulation works with RSS and ECMP based wrt the inner flow. Signed-off-by: Tom Herbert <therbert@google.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--include/net/udp.h29
1 files changed, 29 insertions, 0 deletions
diff --git a/include/net/udp.h b/include/net/udp.h
index 68a1fefe3dfe..70f941368ace 100644
--- a/include/net/udp.h
+++ b/include/net/udp.h
@@ -176,6 +176,35 @@ int udp_lib_get_port(struct sock *sk, unsigned short snum,
176 int (*)(const struct sock *, const struct sock *), 176 int (*)(const struct sock *, const struct sock *),
177 unsigned int hash2_nulladdr); 177 unsigned int hash2_nulladdr);
178 178
179static inline __be16 udp_flow_src_port(struct net *net, struct sk_buff *skb,
180 int min, int max, bool use_eth)
181{
182 u32 hash;
183
184 if (min >= max) {
185 /* Use default range */
186 inet_get_local_port_range(net, &min, &max);
187 }
188
189 hash = skb_get_hash(skb);
190 if (unlikely(!hash) && use_eth) {
191 /* Can't find a normal hash, caller has indicated an Ethernet
192 * packet so use that to compute a hash.
193 */
194 hash = jhash(skb->data, 2 * ETH_ALEN,
195 (__force u32) skb->protocol);
196 }
197
198 /* Since this is being sent on the wire obfuscate hash a bit
199 * to minimize possbility that any useful information to an
200 * attacker is leaked. Only upper 16 bits are relevant in the
201 * computation for 16 bit port value.
202 */
203 hash ^= hash << 16;
204
205 return htons((((u64) hash * (max - min)) >> 32) + min);
206}
207
179/* net/ipv4/udp.c */ 208/* net/ipv4/udp.c */
180void udp_v4_early_demux(struct sk_buff *skb); 209void udp_v4_early_demux(struct sk_buff *skb);
181int udp_get_port(struct sock *sk, unsigned short snum, 210int udp_get_port(struct sock *sk, unsigned short snum,