Commit 25695853 authored by Manish Chopra's avatar Manish Chopra Committed by David S. Miller

qede: Prevent GSO on long Geneve headers

Due to hardware limitation, when transmitting a geneve-encapsulated
packet with more than 32 bytes worth of geneve options the hardware
would not be able to crack the packet and consider it a regular UDP
packet.

This implements the ndo_features_check() in qede in order to prevent
GSO on said transmitted packets.
Signed-off-by: default avatarManish Chopra <manish.chopra@caviumnetworks.com>
Signed-off-by: default avatarYuval Mintz <Yuval.Mintz@caviumnetworks.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent a150241c
...@@ -2240,6 +2240,40 @@ static void qede_udp_tunnel_del(struct net_device *dev, ...@@ -2240,6 +2240,40 @@ static void qede_udp_tunnel_del(struct net_device *dev,
schedule_delayed_work(&edev->sp_task, 0); schedule_delayed_work(&edev->sp_task, 0);
} }
/* 8B udp header + 8B base tunnel header + 32B option length */
#define QEDE_MAX_TUN_HDR_LEN 48
static netdev_features_t qede_features_check(struct sk_buff *skb,
struct net_device *dev,
netdev_features_t features)
{
if (skb->encapsulation) {
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;
}
/* Disable offloads for geneve tunnels, as HW can't parse
* the geneve header which has option length greater than 32B.
*/
if ((l4_proto == IPPROTO_UDP) &&
((skb_inner_mac_header(skb) -
skb_transport_header(skb)) > QEDE_MAX_TUN_HDR_LEN))
return features & ~(NETIF_F_CSUM_MASK |
NETIF_F_GSO_MASK);
}
return features;
}
static const struct net_device_ops qede_netdev_ops = { static const struct net_device_ops qede_netdev_ops = {
.ndo_open = qede_open, .ndo_open = qede_open,
.ndo_stop = qede_close, .ndo_stop = qede_close,
...@@ -2264,6 +2298,7 @@ static const struct net_device_ops qede_netdev_ops = { ...@@ -2264,6 +2298,7 @@ static const struct net_device_ops qede_netdev_ops = {
#endif #endif
.ndo_udp_tunnel_add = qede_udp_tunnel_add, .ndo_udp_tunnel_add = qede_udp_tunnel_add,
.ndo_udp_tunnel_del = qede_udp_tunnel_del, .ndo_udp_tunnel_del = qede_udp_tunnel_del,
.ndo_features_check = qede_features_check,
}; };
/* ------------------------------------------------------------------------- /* -------------------------------------------------------------------------
......
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