Use kernel function to update checksum.

Signed-off-by: Pravin B Shelar <pshe...@ovn.org>
---
 acinclude.m4                                 |  1 +
 datapath/actions.c                           |  8 +++-----
 datapath/linux/compat/include/linux/skbuff.h | 20 ++++++++++++++++++++
 datapath/vport-netdev.c                      |  2 +-
 datapath/vport.h                             |  7 -------
 5 files changed, 25 insertions(+), 13 deletions(-)

diff --git a/acinclude.m4 b/acinclude.m4
index bb0d90a..345cdae 100644
--- a/acinclude.m4
+++ b/acinclude.m4
@@ -556,6 +556,7 @@ AC_DEFUN([OVS_CHECK_LINUX_COMPAT], [
   OVS_GREP_IFELSE([$KSRC/include/linux/skbuff.h], [skb_vlan_pop])
   OVS_GREP_IFELSE([$KSRC/include/linux/skbuff.h], [skb_vlan_push])
   OVS_GREP_IFELSE([$KSRC/include/linux/skbuff.h], [skb_clear_hash_if_not_l4])
+  OVS_GREP_IFELSE([$KSRC/include/linux/skbuff.h], [skb_postpush_rcsum])
 
   OVS_GREP_IFELSE([$KSRC/include/linux/types.h], [bool],
                   [OVS_DEFINE([HAVE_BOOL_TYPE])])
diff --git a/datapath/actions.c b/datapath/actions.c
index 757a8f6..ed44ead 100644
--- a/datapath/actions.c
+++ b/datapath/actions.c
@@ -160,9 +160,7 @@ static int push_mpls(struct sk_buff *skb, struct 
sw_flow_key *key,
        new_mpls_lse = (__be32 *)skb_mpls_header(skb);
        *new_mpls_lse = mpls->mpls_lse;
 
-       if (skb->ip_summed == CHECKSUM_COMPLETE)
-               skb->csum = csum_add(skb->csum, csum_partial(new_mpls_lse,
-                                                            MPLS_HLEN, 0));
+       skb_postpush_rcsum(skb, new_mpls_lse, MPLS_HLEN);
 
        hdr = eth_hdr(skb);
        hdr->h_proto = mpls->mpls_ethertype;
@@ -281,7 +279,7 @@ static int set_eth_addr(struct sk_buff *skb, struct 
sw_flow_key *flow_key,
        ether_addr_copy_masked(eth_hdr(skb)->h_dest, key->eth_dst,
                               mask->eth_dst);
 
-       ovs_skb_postpush_rcsum(skb, eth_hdr(skb), ETH_ALEN * 2);
+       skb_postpush_rcsum(skb, eth_hdr(skb), ETH_ALEN * 2);
 
        ether_addr_copy(flow_key->eth.src, eth_hdr(skb)->h_source);
        ether_addr_copy(flow_key->eth.dst, eth_hdr(skb)->h_dest);
@@ -641,7 +639,7 @@ static int ovs_vport_output(OVS_VPORT_OUTPUT_PARAMS)
        /* Reconstruct the MAC header.  */
        skb_push(skb, data->l2_len);
        memcpy(skb->data, &data->l2_data, data->l2_len);
-       ovs_skb_postpush_rcsum(skb, skb->data, data->l2_len);
+       skb_postpush_rcsum(skb, skb->data, data->l2_len);
        skb_reset_mac_header(skb);
 
        ovs_vport_send(vport, skb);
diff --git a/datapath/linux/compat/include/linux/skbuff.h 
b/datapath/linux/compat/include/linux/skbuff.h
index 16e3590..4511ac0 100644
--- a/datapath/linux/compat/include/linux/skbuff.h
+++ b/datapath/linux/compat/include/linux/skbuff.h
@@ -348,4 +348,24 @@ static inline void skb_clear_hash_if_not_l4(struct sk_buff 
*skb)
                skb_clear_hash(skb);
 }
 #endif
+
+#ifndef HAVE_SKB_POSTPUSH_RCSUM
+static inline void skb_postpush_rcsum(struct sk_buff *skb,
+                                     const void *start, unsigned int len)
+{
+       /* For performing the reverse operation to skb_postpull_rcsum(),
+        * we can instead of ...
+        *
+        *   skb->csum = csum_add(skb->csum, csum_partial(start, len, 0));
+        *
+        * ... just use this equivalent version here to save a few
+        * instructions. Feeding csum of 0 in csum_partial() and later
+        * on adding skb->csum is equivalent to feed skb->csum in the
+        * first place.
+        */
+       if (skb->ip_summed == CHECKSUM_COMPLETE)
+               skb->csum = csum_partial(start, len, skb->csum);
+}
+#endif
+
 #endif
diff --git a/datapath/vport-netdev.c b/datapath/vport-netdev.c
index 2d081c2..905b125 100644
--- a/datapath/vport-netdev.c
+++ b/datapath/vport-netdev.c
@@ -59,7 +59,7 @@ void netdev_port_receive(struct sk_buff *skb, struct 
ip_tunnel_info *tun_info)
                return;
 
        skb_push(skb, ETH_HLEN);
-       ovs_skb_postpush_rcsum(skb, skb->data, ETH_HLEN);
+       skb_postpush_rcsum(skb, skb->data, ETH_HLEN);
        ovs_vport_receive(vport, skb, tun_info);
        return;
 error:
diff --git a/datapath/vport.h b/datapath/vport.h
index 96a5b2b..c9f46f2 100644
--- a/datapath/vport.h
+++ b/datapath/vport.h
@@ -187,13 +187,6 @@ static inline struct vport *vport_from_priv(void *priv)
 int ovs_vport_receive(struct vport *, struct sk_buff *,
                      const struct ip_tunnel_info *);
 
-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));
-}
-
 static inline const char *ovs_vport_name(struct vport *vport)
 {
        return vport->dev->name;
-- 
1.9.1

_______________________________________________
dev mailing list
dev@openvswitch.org
http://openvswitch.org/mailman/listinfo/dev

Reply via email to