struct vxlan_metadata *md, u32 vxflags,
bool udp_sum)
{
+ int type = udp_sum ? SKB_GSO_UDP_TUNNEL_CSUM : SKB_GSO_UDP_TUNNEL;
+ __be16 inner_protocol = htons(ETH_P_TEB);
struct vxlanhdr *vxh;
+ bool double_encap;
int min_headroom;
int err;
- int type = udp_sum ? SKB_GSO_UDP_TUNNEL_CSUM : SKB_GSO_UDP_TUNNEL;
- __be16 inner_protocol = htons(ETH_P_TEB);
if ((vxflags & VXLAN_F_REMCSUM_TX) &&
skb->ip_summed == CHECKSUM_PARTIAL) {
if (unlikely(err))
return err;
+ double_encap = udp_tunnel_handle_partial(skb);
err = iptunnel_handle_offloads(skb, type);
if (err)
return err;
inner_protocol = skb->protocol;
}
- skb_set_inner_protocol(skb, inner_protocol);
+ udp_tunnel_set_inner_protocol(skb, double_encap, inner_protocol);
return 0;
}
dev->features |= NETIF_F_RXCSUM;
dev->features |= NETIF_F_GSO_SOFTWARE;
+ /* Partial features are disabled by default. */
dev->vlan_features = dev->features;
dev->hw_features |= NETIF_F_SG | NETIF_F_HW_CSUM | NETIF_F_FRAGLIST;
dev->hw_features |= NETIF_F_RXCSUM;
dev->hw_features |= NETIF_F_GSO_SOFTWARE;
+ dev->hw_features |= UDP_TUNNEL_PARTIAL_FEATURES;
+ dev->hw_features |= NETIF_F_GSO_PARTIAL;
+
+ dev->hw_enc_features = dev->hw_features;
+ dev->gso_partial_features = UDP_TUNNEL_PARTIAL_FEATURES;
+ dev->mangleid_features = NETIF_F_GSO_PARTIAL;
+
netif_keep_dst(dev);
dev->priv_flags |= IFF_NO_QUEUE;
dev->change_proto_down = true;