openvswitch: make skb->csum consistent with rest of networking stack.
authorPravin B Shelar <pshelar@nicira.com>
Thu, 13 Jun 2013 18:11:44 +0000 (11:11 -0700)
committerJesse Gross <jesse@nicira.com>
Fri, 14 Jun 2013 22:09:12 +0000 (15:09 -0700)
Following patch keeps skb->csum correct across ovs.

Signed-off-by: Pravin B Shelar <pshelar@nicira.com>
Signed-off-by: Jesse Gross <jesse@nicira.com>
net/openvswitch/actions.c
net/openvswitch/flow.c
net/openvswitch/vport-internal_dev.c
net/openvswitch/vport-netdev.c
net/openvswitch/vport.h

index 894b6cbdd9295841e6782268b8743fcb63358391..596d6373399dcb75275f13e8ae2637c15aec11e7 100644 (file)
@@ -130,9 +130,13 @@ static int set_eth_addr(struct sk_buff *skb,
        if (unlikely(err))
                return err;
 
+       skb_postpull_rcsum(skb, eth_hdr(skb), ETH_ALEN * 2);
+
        memcpy(eth_hdr(skb)->h_source, eth_key->eth_src, ETH_ALEN);
        memcpy(eth_hdr(skb)->h_dest, eth_key->eth_dst, ETH_ALEN);
 
+       ovs_skb_postpush_rcsum(skb, eth_hdr(skb), ETH_ALEN * 2);
+
        return 0;
 }
 
index 33df0913358d3c05f0f0b4c865d6e394e23c3197..fca483360ce24db0462b91d4efdfad4deeda681b 100644 (file)
@@ -618,6 +618,9 @@ 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(skb->vlan_tci);
index 84e0a03791867449247cc0c161ab434f9a6e5c15..e284c7e1fec441b427fc52c72505952dab84fcbb 100644 (file)
@@ -221,6 +221,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);
+       skb_postpull_rcsum(skb, eth_hdr(skb), ETH_HLEN);
 
        netif_rx(skb);
 
index 43712217a372f405ec0fd0047674cabf42b6164f..40de815b421383ac301d264265ebee210eb1a639 100644 (file)
@@ -49,6 +49,8 @@ static void netdev_port_receive(struct vport *vport, struct sk_buff *skb)
                return;
 
        skb_push(skb, ETH_HLEN);
+       ovs_skb_postpush_rcsum(skb, skb->data, ETH_HLEN);
+
        ovs_vport_receive(vport, skb);
        return;
 
index 1cef5cd3be47681f0a2cc2950d47bf75cd8ffaf2..293278c4c2df8b3774074af997fe0a1125bc74b7 100644 (file)
@@ -192,4 +192,11 @@ void ovs_vport_record_error(struct vport *, enum vport_err_type err_type);
 extern const struct vport_ops ovs_netdev_vport_ops;
 extern const struct vport_ops ovs_internal_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 */