benet: stricter vxlan offloading check in be_features_check
authorSabrina Dubroca <sd@queasysnail.net>
Tue, 3 Jan 2017 15:26:04 +0000 (16:26 +0100)
committerDavid S. Miller <davem@davemloft.net>
Tue, 3 Jan 2017 15:58:43 +0000 (10:58 -0500)
When VXLAN offloading is enabled, be_features_check() tries to check if
an encapsulated packet is indeed a VXLAN packet. The check is not strict
enough, and considers any UDP-encapsulated ethernet frame with a 8-byte
tunnel header as being VXLAN. Unfortunately, both GENEVE and VXLAN-GPE
have a 8-byte header, so they get through this check.

Force the UDP destination port to be the one that has been offloaded to
hardware.

Without this, GENEVE-encapsulated packets can end up having an incorrect
checksum when both a GENEVE and a VXLAN (offloaded) tunnel are
configured.

This is similar to commit a547224dceed ("mlx4e: Do not attempt to
offload VXLAN ports that are unrecognized").

Signed-off-by: Sabrina Dubroca <sd@queasysnail.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/emulex/benet/be_main.c

index 7e1633bf5a22ccf1c9c123ba541349b5dfea1064..225e9a4877d7b16e058cfa7c0dac9ccb5434bb5b 100644 (file)
@@ -5155,7 +5155,9 @@ static netdev_features_t be_features_check(struct sk_buff *skb,
            skb->inner_protocol_type != ENCAP_TYPE_ETHER ||
            skb->inner_protocol != htons(ETH_P_TEB) ||
            skb_inner_mac_header(skb) - skb_transport_header(skb) !=
-           sizeof(struct udphdr) + sizeof(struct vxlanhdr))
+               sizeof(struct udphdr) + sizeof(struct vxlanhdr) ||
+           !adapter->vxlan_port ||
+           udp_hdr(skb)->dest != adapter->vxlan_port)
                return features & ~(NETIF_F_CSUM_MASK | NETIF_F_GSO_MASK);
 
        return features;