datapath: add ipv6 'set' action
[openvswitch] / datapath / checksum.h
index 0e2db4ceb776cd1dd2bfe78e66dbce7cd5d6a15b..a440c59985ca94a17c5dac620248b345767a5404 100644 (file)
@@ -1,9 +1,19 @@
 /*
- * Copyright (c) 2010, 2011 Nicira Networks.
- * Distributed under the terms of the GNU GPL version 2.
+ * Copyright (c) 2007-2011 Nicira, Inc.
  *
- * Significant portions of this file may be copied from parts of the Linux
- * kernel, by Linus Torvalds and others.
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA
  */
 
 #ifndef CHECKSUM_H
@@ -92,6 +102,30 @@ static inline void inet_proto_csum_replace4(__sum16 *sum, struct sk_buff *skb,
 }
 #endif
 
+#if defined(NEED_CSUM_NORMALIZE) || LINUX_VERSION_CODE < KERNEL_VERSION(3,7,0)
+#define inet_proto_csum_replace16 rpl_inet_proto_csum_replace16
+static inline void inet_proto_csum_replace16(__sum16 *sum,
+                                            struct sk_buff *skb,
+                                            const __be32 *from,
+                                            const __be32 *to,
+                                            int pseudohdr)
+{
+       __be32 diff[] = {
+               ~from[0], ~from[1], ~from[2], ~from[3],
+               to[0], to[1], to[2], to[3],
+       };
+       if (get_ip_summed(skb) != OVS_CSUM_PARTIAL) {
+               *sum = csum_fold(csum_partial(diff, sizeof(diff),
+                                ~csum_unfold(*sum)));
+               if (get_ip_summed(skb) == OVS_CSUM_COMPLETE && pseudohdr)
+                       skb->csum = ~csum_partial(diff, sizeof(diff),
+                                                 ~skb->csum);
+       } else if (pseudohdr)
+               *sum = ~csum_fold(csum_partial(diff, sizeof(diff),
+                                 csum_unfold(*sum)));
+}
+#endif
+
 #ifdef NEED_CSUM_NORMALIZE
 static inline void update_csum_start(struct sk_buff *skb, int delta)
 {