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