Skip to content

Commit

Permalink
vmxnet3: fix cksum offload issues for non-udp tunnels
Browse files Browse the repository at this point in the history
Commit dacce2b ("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: dacce2b ("vmxnet3: add geneve and vxlan tunnel offload support")
Signed-off-by: Ronak Doshi <doshir@vmware.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Ronak Doshi authored and David S. Miller committed Sep 25, 2020
1 parent abe2f12 commit 1dac3b1
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 3 deletions.
5 changes: 2 additions & 3 deletions drivers/net/vmxnet3/vmxnet3_drv.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
union Vmxnet3_GenericDesc tempTxDesc;
#endif
struct udphdr *udph;

count = txd_estimate(skb);

Expand Down Expand Up @@ -1135,8 +1134,7 @@ vmxnet3_tq_xmit(struct sk_buff *skb, struct vmxnet3_tx_queue *tq,
gdesc->txd.om = VMXNET3_OM_ENCAP;
gdesc->txd.msscof = ctx.mss;

udph = udp_hdr(skb);
if (udph->check)
if (skb_shinfo(skb)->gso_type & SKB_GSO_UDP_TUNNEL_CSUM)
gdesc->txd.oco = 1;
} else {
gdesc->txd.hlen = ctx.l4_offset + ctx.l4_hdr_size;
Expand Down Expand Up @@ -3371,6 +3369,7 @@ vmxnet3_probe_device(struct pci_dev *pdev,
.ndo_change_mtu = vmxnet3_change_mtu,
.ndo_fix_features = vmxnet3_fix_features,
.ndo_set_features = vmxnet3_set_features,
.ndo_features_check = vmxnet3_features_check,
.ndo_get_stats64 = vmxnet3_get_stats64,
.ndo_tx_timeout = vmxnet3_tx_timeout,
.ndo_set_rx_mode = vmxnet3_set_mc,
Expand Down
28 changes: 28 additions & 0 deletions drivers/net/vmxnet3/vmxnet3_ethtool.c
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,34 @@ netdev_features_t vmxnet3_fix_features(struct net_device *netdev,
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)
{
struct vmxnet3_adapter *adapter = netdev_priv(netdev);
Expand Down
4 changes: 4 additions & 0 deletions drivers/net/vmxnet3/vmxnet3_int.h
Original file line number Diff line number Diff line change
Expand Up @@ -470,6 +470,10 @@ vmxnet3_rq_destroy_all(struct vmxnet3_adapter *adapter);
netdev_features_t
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
vmxnet3_set_features(struct net_device *netdev, netdev_features_t features);

Expand Down

0 comments on commit 1dac3b1

Please sign in to comment.