Commit 1dac3b1b authored by Ronak Doshi's avatar Ronak Doshi Committed by David S. Miller

vmxnet3: fix cksum offload issues for non-udp tunnels

Commit dacce2be ("vmxnet3: add geneve and vxlan tunnel offload
support") added support for encapsulation offload. However, the inner
offload capability is to be restrictued to UDP tunnels.

This patch fixes the issue for non-udp tunnels by adding features
check capability and filtering appropriate features for non-udp tunnels.

Fixes: dacce2be ("vmxnet3: add geneve and vxlan tunnel offload support")
Signed-off-by: default avatarRonak Doshi <doshir@vmware.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent abe2f12d
...@@ -1032,7 +1032,6 @@ vmxnet3_tq_xmit(struct sk_buff *skb, struct vmxnet3_tx_queue *tq, ...@@ -1032,7 +1032,6 @@ vmxnet3_tq_xmit(struct sk_buff *skb, struct vmxnet3_tx_queue *tq,
/* Use temporary descriptor to avoid touching bits multiple times */ /* Use temporary descriptor to avoid touching bits multiple times */
union Vmxnet3_GenericDesc tempTxDesc; union Vmxnet3_GenericDesc tempTxDesc;
#endif #endif
struct udphdr *udph;
count = txd_estimate(skb); count = txd_estimate(skb);
...@@ -1135,8 +1134,7 @@ vmxnet3_tq_xmit(struct sk_buff *skb, struct vmxnet3_tx_queue *tq, ...@@ -1135,8 +1134,7 @@ vmxnet3_tq_xmit(struct sk_buff *skb, struct vmxnet3_tx_queue *tq,
gdesc->txd.om = VMXNET3_OM_ENCAP; gdesc->txd.om = VMXNET3_OM_ENCAP;
gdesc->txd.msscof = ctx.mss; gdesc->txd.msscof = ctx.mss;
udph = udp_hdr(skb); if (skb_shinfo(skb)->gso_type & SKB_GSO_UDP_TUNNEL_CSUM)
if (udph->check)
gdesc->txd.oco = 1; gdesc->txd.oco = 1;
} else { } else {
gdesc->txd.hlen = ctx.l4_offset + ctx.l4_hdr_size; gdesc->txd.hlen = ctx.l4_offset + ctx.l4_hdr_size;
...@@ -3371,6 +3369,7 @@ vmxnet3_probe_device(struct pci_dev *pdev, ...@@ -3371,6 +3369,7 @@ vmxnet3_probe_device(struct pci_dev *pdev,
.ndo_change_mtu = vmxnet3_change_mtu, .ndo_change_mtu = vmxnet3_change_mtu,
.ndo_fix_features = vmxnet3_fix_features, .ndo_fix_features = vmxnet3_fix_features,
.ndo_set_features = vmxnet3_set_features, .ndo_set_features = vmxnet3_set_features,
.ndo_features_check = vmxnet3_features_check,
.ndo_get_stats64 = vmxnet3_get_stats64, .ndo_get_stats64 = vmxnet3_get_stats64,
.ndo_tx_timeout = vmxnet3_tx_timeout, .ndo_tx_timeout = vmxnet3_tx_timeout,
.ndo_set_rx_mode = vmxnet3_set_mc, .ndo_set_rx_mode = vmxnet3_set_mc,
......
...@@ -267,6 +267,34 @@ netdev_features_t vmxnet3_fix_features(struct net_device *netdev, ...@@ -267,6 +267,34 @@ netdev_features_t vmxnet3_fix_features(struct net_device *netdev,
return features; return features;
} }
netdev_features_t vmxnet3_features_check(struct sk_buff *skb,
struct net_device *netdev,
netdev_features_t features)
{
struct vmxnet3_adapter *adapter = netdev_priv(netdev);
/* Validate if the tunneled packet is being offloaded by the device */
if (VMXNET3_VERSION_GE_4(adapter) &&
skb->encapsulation && skb->ip_summed == CHECKSUM_PARTIAL) {
u8 l4_proto = 0;
switch (vlan_get_protocol(skb)) {
case htons(ETH_P_IP):
l4_proto = ip_hdr(skb)->protocol;
break;
case htons(ETH_P_IPV6):
l4_proto = ipv6_hdr(skb)->nexthdr;
break;
default:
return features & ~(NETIF_F_CSUM_MASK | NETIF_F_GSO_MASK);
}
if (l4_proto != IPPROTO_UDP)
return features & ~(NETIF_F_CSUM_MASK | NETIF_F_GSO_MASK);
}
return features;
}
static void vmxnet3_enable_encap_offloads(struct net_device *netdev) static void vmxnet3_enable_encap_offloads(struct net_device *netdev)
{ {
struct vmxnet3_adapter *adapter = netdev_priv(netdev); struct vmxnet3_adapter *adapter = netdev_priv(netdev);
......
...@@ -470,6 +470,10 @@ vmxnet3_rq_destroy_all(struct vmxnet3_adapter *adapter); ...@@ -470,6 +470,10 @@ vmxnet3_rq_destroy_all(struct vmxnet3_adapter *adapter);
netdev_features_t netdev_features_t
vmxnet3_fix_features(struct net_device *netdev, netdev_features_t features); vmxnet3_fix_features(struct net_device *netdev, netdev_features_t features);
netdev_features_t
vmxnet3_features_check(struct sk_buff *skb,
struct net_device *netdev, netdev_features_t features);
int int
vmxnet3_set_features(struct net_device *netdev, netdev_features_t features); vmxnet3_set_features(struct net_device *netdev, netdev_features_t features);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment