|
@@ -176,6 +176,35 @@ int udp_lib_get_port(struct sock *sk, unsigned short snum,
|
|
int (*)(const struct sock *, const struct sock *),
|
|
int (*)(const struct sock *, const struct sock *),
|
|
unsigned int hash2_nulladdr);
|
|
unsigned int hash2_nulladdr);
|
|
|
|
|
|
|
|
+static inline __be16 udp_flow_src_port(struct net *net, struct sk_buff *skb,
|
|
|
|
+ int min, int max, bool use_eth)
|
|
|
|
+{
|
|
|
|
+ u32 hash;
|
|
|
|
+
|
|
|
|
+ if (min >= max) {
|
|
|
|
+ /* Use default range */
|
|
|
|
+ inet_get_local_port_range(net, &min, &max);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ hash = skb_get_hash(skb);
|
|
|
|
+ if (unlikely(!hash) && use_eth) {
|
|
|
|
+ /* Can't find a normal hash, caller has indicated an Ethernet
|
|
|
|
+ * packet so use that to compute a hash.
|
|
|
|
+ */
|
|
|
|
+ hash = jhash(skb->data, 2 * ETH_ALEN,
|
|
|
|
+ (__force u32) skb->protocol);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /* Since this is being sent on the wire obfuscate hash a bit
|
|
|
|
+ * to minimize possbility that any useful information to an
|
|
|
|
+ * attacker is leaked. Only upper 16 bits are relevant in the
|
|
|
|
+ * computation for 16 bit port value.
|
|
|
|
+ */
|
|
|
|
+ hash ^= hash << 16;
|
|
|
|
+
|
|
|
|
+ return htons((((u64) hash * (max - min)) >> 32) + min);
|
|
|
|
+}
|
|
|
|
+
|
|
/* net/ipv4/udp.c */
|
|
/* net/ipv4/udp.c */
|
|
void udp_v4_early_demux(struct sk_buff *skb);
|
|
void udp_v4_early_demux(struct sk_buff *skb);
|
|
int udp_get_port(struct sock *sk, unsigned short snum,
|
|
int udp_get_port(struct sock *sk, unsigned short snum,
|