if (unlikely(err))
return err;
+ if (get_ip_summed(skb) == OVS_CSUM_COMPLETE)
+ skb->csum = csum_sub(skb->csum, csum_partial(eth_hdr(skb),
+ ETH_ALEN * 2, 0));
+
memcpy(eth_hdr(skb)->h_source, eth_key->eth_src, ETH_ALEN);
memcpy(eth_hdr(skb)->h_dest, eth_key->eth_dst, ETH_ALEN);
+ if (get_ip_summed(skb) == OVS_CSUM_COMPLETE)
+ skb->csum = csum_add(skb->csum, csum_partial(eth_hdr(skb),
+ ETH_ALEN * 2, 0));
+
return 0;
}
memcpy(key->eth.dst, eth->h_dest, ETH_ALEN);
__skb_pull(skb, 2 * ETH_ALEN);
+ /* We are going to push all headers that we pull, so no need to
+ * update skb->csum here. */
if (vlan_tx_tag_present(skb))
key->eth.tci = htons(vlan_get_tci(skb));
if (unlikely(!skb))
return -ENOMEM;
+ if (get_ip_summed(skb) == OVS_CSUM_COMPLETE)
+ skb->csum = csum_add(skb->csum,
+ csum_partial(skb->data + (2 * ETH_ALEN),
+ VLAN_HLEN, 0));
+
vlan_set_tci(skb, 0);
return 0;
}
tnl_flags = gre_flags_to_tunnel_flags(gre_flags, is_gre64);
tnl_tun_key_init(&tun_key, iph, key, tnl_flags);
- __skb_pull(skb, hdr_len);
- skb_postpull_rcsum(skb, skb_transport_header(skb), hdr_len + ETH_HLEN);
+ skb_pull_rcsum(skb, hdr_len);
ovs_tnl_rcv(vport, skb, &tun_key);
return 0;
skb->dev = netdev;
skb->pkt_type = PACKET_HOST;
skb->protocol = eth_type_trans(skb, netdev);
+ skb_postpull_rcsum(skb, eth_hdr(skb), ETH_HLEN);
forward_ip_summed(skb, false);
netif_rx(skb);
ethh->h_source[0] = 0x02;
ethh->h_proto = protocol;
+ ovs_skb_postpush_rcsum(skb, skb->data, ETH_HLEN);
+
ovs_tnl_rcv(vport_from_priv(lisp_port), skb, &tun_key);
goto out;
if (unlikely(!skb))
return;
- skb_push(skb, ETH_HLEN);
-
if (unlikely(compute_ip_summed(skb, false)))
goto error;
+ skb_push(skb, ETH_HLEN);
+ ovs_skb_postpush_rcsum(skb, skb->data, ETH_HLEN);
+
vlan_copy_skb_tci(skb);
ovs_vport_receive(vport, skb, NULL);
vxh->vx_vni & htonl(0xff)))
goto error;
- __skb_pull(skb, VXLAN_HLEN);
- skb_postpull_rcsum(skb, skb_transport_header(skb), VXLAN_HLEN + ETH_HLEN);
+ skb_pull_rcsum(skb, VXLAN_HLEN);
key = cpu_to_be64(ntohl(vxh->vx_vni) >> 8);
extern const struct vport_ops ovs_vxlan_vport_ops;
extern const struct vport_ops ovs_lisp_vport_ops;
+static inline void ovs_skb_postpush_rcsum(struct sk_buff *skb,
+ const void *start, unsigned int len)
+{
+ if (skb->ip_summed == CHECKSUM_COMPLETE)
+ skb->csum = csum_add(skb->csum, csum_partial(start, len, 0));
+}
#endif /* vport.h */