diff options
author | Shrikrishna Khare <skhare@vmware.com> | 2015-03-01 05:33:09 +0100 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2015-03-02 05:03:42 +0100 |
commit | 759c9359ae5a6ecdb74cad61a31be6805fb09617 (patch) | |
tree | 1325ca274a50b5d805218c3b8dd85f7cf6418861 /drivers/net/vmxnet3/vmxnet3_drv.c | |
parent | Merge branch 'ebpf_support_for_cls_bpf' (diff) | |
download | linux-759c9359ae5a6ecdb74cad61a31be6805fb09617.tar.xz linux-759c9359ae5a6ecdb74cad61a31be6805fb09617.zip |
Driver: Vmxnet3: Copy TCP header to mapped frame for IPv6 packets
Allows for packet parsing to be done by the fast path. This performance
optimization already exists for IPv4. Add similar logic for IPv6.
Signed-off-by: Amitabha Banerjee <banerjeea@vmware.com>
Signed-off-by: Shrikrishna Khare <skhare@vmware.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/vmxnet3/vmxnet3_drv.c')
-rw-r--r-- | drivers/net/vmxnet3/vmxnet3_drv.c | 29 |
1 files changed, 20 insertions, 9 deletions
diff --git a/drivers/net/vmxnet3/vmxnet3_drv.c b/drivers/net/vmxnet3/vmxnet3_drv.c index 294214c15292..61c0840c448c 100644 --- a/drivers/net/vmxnet3/vmxnet3_drv.c +++ b/drivers/net/vmxnet3/vmxnet3_drv.c @@ -819,6 +819,7 @@ vmxnet3_parse_and_copy_hdr(struct sk_buff *skb, struct vmxnet3_tx_queue *tq, struct vmxnet3_adapter *adapter) { struct Vmxnet3_TxDataDesc *tdd; + u8 protocol = 0; if (ctx->mss) { /* TSO */ ctx->eth_ip_hdr_size = skb_transport_offset(skb); @@ -831,16 +832,25 @@ vmxnet3_parse_and_copy_hdr(struct sk_buff *skb, struct vmxnet3_tx_queue *tq, if (ctx->ipv4) { const struct iphdr *iph = ip_hdr(skb); - if (iph->protocol == IPPROTO_TCP) - ctx->l4_hdr_size = tcp_hdrlen(skb); - else if (iph->protocol == IPPROTO_UDP) - ctx->l4_hdr_size = sizeof(struct udphdr); - else - ctx->l4_hdr_size = 0; - } else { - /* for simplicity, don't copy L4 headers */ + protocol = iph->protocol; + } else if (ctx->ipv6) { + const struct ipv6hdr *ipv6h = ipv6_hdr(skb); + + protocol = ipv6h->nexthdr; + } + + switch (protocol) { + case IPPROTO_TCP: + ctx->l4_hdr_size = tcp_hdrlen(skb); + break; + case IPPROTO_UDP: + ctx->l4_hdr_size = sizeof(struct udphdr); + break; + default: ctx->l4_hdr_size = 0; + break; } + ctx->copy_size = min(ctx->eth_ip_hdr_size + ctx->l4_hdr_size, skb->len); } else { @@ -887,7 +897,7 @@ vmxnet3_prepare_tso(struct sk_buff *skb, iph->check = 0; tcph->check = ~csum_tcpudp_magic(iph->saddr, iph->daddr, 0, IPPROTO_TCP, 0); - } else { + } else if (ctx->ipv6) { struct ipv6hdr *iph = ipv6_hdr(skb); tcph->check = ~csum_ipv6_magic(&iph->saddr, &iph->daddr, 0, @@ -938,6 +948,7 @@ vmxnet3_tq_xmit(struct sk_buff *skb, struct vmxnet3_tx_queue *tq, count = txd_estimate(skb); ctx.ipv4 = (vlan_get_protocol(skb) == cpu_to_be16(ETH_P_IP)); + ctx.ipv6 = (vlan_get_protocol(skb) == cpu_to_be16(ETH_P_IPV6)); ctx.mss = skb_shinfo(skb)->gso_size; if (ctx.mss) { |