[ovs-dev] [PATCH] datapath: make skb->csum consistent with rest of networking stack.

Pravin B Shelar pshelar at nicira.com
Mon Jun 10 22:56:22 UTC 2013


As suggested by Jesse in the comment for patch "gre: Restructure
tunneling", following patch keeps skb->csum correct across ovs.

Signed-off-by: Pravin B Shelar <pshelar at nicira.com>
---
 datapath/actions.c            |    8 ++++++++
 datapath/flow.c               |    2 ++
 datapath/vport-gre.c          |    3 +--
 datapath/vport-internal_dev.c |    3 ++-
 datapath/vport-netdev.c       |    7 +++++--
 datapath/vport-vxlan.c        |    3 +--
 6 files changed, 19 insertions(+), 7 deletions(-)

diff --git a/datapath/actions.c b/datapath/actions.c
index 0dac658..6d60cd0 100644
--- a/datapath/actions.c
+++ b/datapath/actions.c
@@ -132,9 +132,17 @@ static int set_eth_addr(struct sk_buff *skb,
 	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_HLEN, 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_HLEN, 0));
+
 	return 0;
 }
 
diff --git a/datapath/flow.c b/datapath/flow.c
index 7f897bd..7604405 100644
--- a/datapath/flow.c
+++ b/datapath/flow.c
@@ -636,6 +636,8 @@ int ovs_flow_extract(struct sk_buff *skb, u16 in_port, struct sw_flow_key *key,
 	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));
diff --git a/datapath/vport-gre.c b/datapath/vport-gre.c
index add17d9..dae35ac 100644
--- a/datapath/vport-gre.c
+++ b/datapath/vport-gre.c
@@ -271,8 +271,7 @@ static int gre_rcv(struct sk_buff *skb)
 	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;
diff --git a/datapath/vport-internal_dev.c b/datapath/vport-internal_dev.c
index 9a159cd..4fdbc59 100644
--- a/datapath/vport-internal_dev.c
+++ b/datapath/vport-internal_dev.c
@@ -267,6 +267,7 @@ static int internal_dev_recv(struct vport *vport, struct sk_buff *skb)
 	struct net_device *netdev = netdev_vport_priv(vport)->dev;
 	int len;
 
+	forward_ip_summed(skb, false);
 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,37)
 	if (unlikely(vlan_deaccel_tag(skb)))
 		return 0;
@@ -281,7 +282,7 @@ static int internal_dev_recv(struct vport *vport, struct sk_buff *skb)
 	skb->dev = netdev;
 	skb->pkt_type = PACKET_HOST;
 	skb->protocol = eth_type_trans(skb, netdev);
-	forward_ip_summed(skb, false);
+	skb_postpull_rcsum(skb, eth_hdr(skb), ETH_HLEN);
 
 	netif_rx(skb);
 
diff --git a/datapath/vport-netdev.c b/datapath/vport-netdev.c
index 4e7342c..0537386 100644
--- a/datapath/vport-netdev.c
+++ b/datapath/vport-netdev.c
@@ -256,11 +256,14 @@ static void netdev_port_receive(struct vport *vport, struct sk_buff *skb)
 	if (unlikely(!skb))
 		return;
 
-	skb_push(skb, ETH_HLEN);
-
 	if (unlikely(compute_ip_summed(skb, false)))
 		goto error;
 
+	skb_push(skb, ETH_HLEN);
+	if (get_ip_summed(skb) == OVS_CSUM_COMPLETE)
+		skb->csum = csum_add(skb->csum, csum_partial(skb->data,
+							     ETH_HLEN, 0));
+
 	vlan_copy_skb_tci(skb);
 
 	ovs_vport_receive(vport, skb, NULL);
diff --git a/datapath/vport-vxlan.c b/datapath/vport-vxlan.c
index d140c3b..708283e 100644
--- a/datapath/vport-vxlan.c
+++ b/datapath/vport-vxlan.c
@@ -129,8 +129,7 @@ static int vxlan_rcv(struct sock *sk, struct sk_buff *skb)
 		     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);
 
-- 
1.7.1




More information about the dev mailing list