Skip to content

Commit

Permalink
hyperv: Add handling of IP header with option field in netvsc_set_hash()
Browse files Browse the repository at this point in the history
In case that the IP header has optional field at the end, this patch will
get the port numbers after that field, and compute the hash. The general
parser skb_flow_dissect() is used here.

Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com>
Reviewed-by: K. Y. Srinivasan <kys@microsoft.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Haiyang Zhang authored and David S. Miller committed Oct 18, 2014
1 parent f47de06 commit f88e671
Showing 1 changed file with 10 additions and 16 deletions.
26 changes: 10 additions & 16 deletions drivers/net/hyperv/netvsc_drv.c
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ union sub_key {
* data: network byte order
* return: host byte order
*/
static u32 comp_hash(u8 *key, int klen, u8 *data, int dlen)
static u32 comp_hash(u8 *key, int klen, void *data, int dlen)
{
union sub_key subk;
int k_next = 4;
Expand All @@ -176,7 +176,7 @@ static u32 comp_hash(u8 *key, int klen, u8 *data, int dlen)
for (i = 0; i < dlen; i++) {
subk.kb = key[k_next];
k_next = (k_next + 1) % klen;
dt = data[i];
dt = ((u8 *)data)[i];
for (j = 0; j < 8; j++) {
if (dt & 0x80)
ret ^= subk.ka;
Expand All @@ -190,26 +190,20 @@ static u32 comp_hash(u8 *key, int klen, u8 *data, int dlen)

static bool netvsc_set_hash(u32 *hash, struct sk_buff *skb)
{
struct iphdr *iphdr;
struct flow_keys flow;
int data_len;
bool ret = false;

if (eth_hdr(skb)->h_proto != htons(ETH_P_IP))
if (!skb_flow_dissect(skb, &flow) || flow.n_proto != htons(ETH_P_IP))
return false;

iphdr = ip_hdr(skb);
if (flow.ip_proto == IPPROTO_TCP)
data_len = 12;
else
data_len = 8;

if (iphdr->version == 4) {
if (iphdr->protocol == IPPROTO_TCP)
data_len = 12;
else
data_len = 8;
*hash = comp_hash(netvsc_hash_key, HASH_KEYLEN,
(u8 *)&iphdr->saddr, data_len);
ret = true;
}
*hash = comp_hash(netvsc_hash_key, HASH_KEYLEN, &flow, data_len);

return ret;
return true;
}

static u16 netvsc_select_queue(struct net_device *ndev, struct sk_buff *skb,
Expand Down

0 comments on commit f88e671

Please sign in to comment.