|
@@ -191,6 +191,36 @@ static void *init_ppi_data(struct rndis_message *msg, u32 ppi_size,
|
|
|
return ppi;
|
|
|
}
|
|
|
|
|
|
+/* Azure hosts don't support non-TCP port numbers in hashing yet. We compute
|
|
|
+ * hash for non-TCP traffic with only IP numbers.
|
|
|
+ */
|
|
|
+static inline u32 netvsc_get_hash(struct sk_buff *skb, struct sock *sk)
|
|
|
+{
|
|
|
+ struct flow_keys flow;
|
|
|
+ u32 hash;
|
|
|
+ static u32 hashrnd __read_mostly;
|
|
|
+
|
|
|
+ net_get_random_once(&hashrnd, sizeof(hashrnd));
|
|
|
+
|
|
|
+ if (!skb_flow_dissect_flow_keys(skb, &flow, 0))
|
|
|
+ return 0;
|
|
|
+
|
|
|
+ if (flow.basic.ip_proto == IPPROTO_TCP) {
|
|
|
+ return skb_get_hash(skb);
|
|
|
+ } else {
|
|
|
+ if (flow.basic.n_proto == htons(ETH_P_IP))
|
|
|
+ hash = jhash2((u32 *)&flow.addrs.v4addrs, 2, hashrnd);
|
|
|
+ else if (flow.basic.n_proto == htons(ETH_P_IPV6))
|
|
|
+ hash = jhash2((u32 *)&flow.addrs.v6addrs, 8, hashrnd);
|
|
|
+ else
|
|
|
+ hash = 0;
|
|
|
+
|
|
|
+ skb_set_hash(skb, hash, PKT_HASH_TYPE_L3);
|
|
|
+ }
|
|
|
+
|
|
|
+ return hash;
|
|
|
+}
|
|
|
+
|
|
|
static inline int netvsc_get_tx_queue(struct net_device *ndev,
|
|
|
struct sk_buff *skb, int old_idx)
|
|
|
{
|
|
@@ -198,7 +228,7 @@ static inline int netvsc_get_tx_queue(struct net_device *ndev,
|
|
|
struct sock *sk = skb->sk;
|
|
|
int q_idx;
|
|
|
|
|
|
- q_idx = ndc->tx_send_table[skb_get_hash(skb) &
|
|
|
+ q_idx = ndc->tx_send_table[netvsc_get_hash(skb, sk) &
|
|
|
(VRSS_SEND_TAB_SIZE - 1)];
|
|
|
|
|
|
/* If queue index changed record the new value */
|