}
static netdev_features_t harmonize_features(struct sk_buff *skb,
- __be16 protocol, netdev_features_t features)
+ netdev_features_t features)
{
if (skb->ip_summed != CHECKSUM_NONE &&
- !can_checksum_protocol(features, protocol)) {
+ !can_checksum_protocol(features, skb_network_protocol(skb))) {
features &= ~NETIF_F_ALL_CSUM;
} else if (illegal_highdma(skb->dev, skb)) {
features &= ~NETIF_F_SG;
struct vlan_ethhdr *veh = (struct vlan_ethhdr *)skb->data;
protocol = veh->h_vlan_encapsulated_proto;
} else if (!vlan_tx_tag_present(skb)) {
- return harmonize_features(skb, protocol, features);
+ return harmonize_features(skb, features);
}
features &= (skb->dev->vlan_features | NETIF_F_HW_VLAN_CTAG_TX |
NETIF_F_HW_VLAN_STAG_TX);
- if (protocol != htons(ETH_P_8021Q) && protocol != htons(ETH_P_8021AD)) {
- return harmonize_features(skb, protocol, features);
- } else {
+ if (protocol == htons(ETH_P_8021Q) || protocol == htons(ETH_P_8021AD))
features &= NETIF_F_SG | NETIF_F_HIGHDMA | NETIF_F_FRAGLIST |
NETIF_F_GEN_CSUM | NETIF_F_HW_VLAN_CTAG_TX |
NETIF_F_HW_VLAN_STAG_TX;
- return harmonize_features(skb, protocol, features);
- }
+
+ return harmonize_features(skb, features);
}
EXPORT_SYMBOL(netif_skb_features);
}
__skb_push(skb, tnl_hlen - ghl);
+ skb_reset_inner_headers(skb);
+ skb->encapsulation = 1;
+
skb_reset_mac_header(skb);
skb_set_network_header(skb, mac_len);
skb->mac_len = mac_len;
struct udphdr *uh;
int udp_offset = outer_hlen - tnl_hlen;
+ skb_reset_inner_headers(skb);
+ skb->encapsulation = 1;
+
skb->mac_len = mac_len;
skb_push(skb, outer_hlen);
uh->check = CSUM_MANGLED_0;
}
- skb->ip_summed = CHECKSUM_NONE;
skb->protocol = protocol;
} while ((skb = skb->next));
out: