Upstream commit:
udp: Generic functions to set checksum
Added udp_set_csum and udp6_set_csum functions to set UDP checksums
in packets. These are for simple UDP packets such as those that might
be created in UDP tunnels.
Signed-off-by: Tom Herbert <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
Upstream: af5fcba7 ("udp: Generic functions to set checksum")
Signed-off-by: Jesse Gross <[email protected]>
---
datapath/linux/.gitignore | 1 +
datapath/linux/Modules.mk | 1 +
datapath/linux/compat/include/net/udp.h | 12 +++++++++
datapath/linux/compat/udp.c | 43 +++++++++++++++++++++++++++++++++
4 files changed, 57 insertions(+)
create mode 100644 datapath/linux/compat/udp.c
diff --git a/datapath/linux/.gitignore b/datapath/linux/.gitignore
index fb19d78..2fb1198 100644
--- a/datapath/linux/.gitignore
+++ b/datapath/linux/.gitignore
@@ -38,6 +38,7 @@
/time.c
/tmp
/tunnel.c
+/udp.c
/udp_tunnel.c
/utils.c
/vlan.c
diff --git a/datapath/linux/Modules.mk b/datapath/linux/Modules.mk
index 945f859..53865da 100644
--- a/datapath/linux/Modules.mk
+++ b/datapath/linux/Modules.mk
@@ -11,6 +11,7 @@ openvswitch_sources += \
linux/compat/net_namespace.c \
linux/compat/reciprocal_div.c \
linux/compat/skbuff-openvswitch.c \
+ linux/compat/udp.c \
linux/compat/udp_tunnel.c \
linux/compat/vxlan.c \
linux/compat/utils.c
diff --git a/datapath/linux/compat/include/net/udp.h
b/datapath/linux/compat/include/net/udp.h
index 88174ae..f1841d4 100644
--- a/datapath/linux/compat/include/net/udp.h
+++ b/datapath/linux/compat/include/net/udp.h
@@ -1,6 +1,7 @@
#ifndef __NET_UDP_WRAPPER_H
#define __NET_UDP_WRAPPER_H 1
+#include <linux/version.h>
#include_next <net/udp.h>
#ifndef HAVE_UDP_FLOW_SRC_PORT
@@ -34,4 +35,15 @@ static inline __be16 udp_flow_src_port(struct net *net,
struct sk_buff *skb,
}
#endif
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3,16,0)
+static inline __sum16 udp_v4_check(int len, __be32 saddr,
+ __be32 daddr, __wsum base)
+{
+ return csum_tcpudp_magic(saddr, daddr, len, IPPROTO_UDP, base);
+}
+
+void udp_set_csum(bool nocheck, struct sk_buff *skb,
+ __be32 saddr, __be32 daddr, int len);
+#endif
+
#endif
diff --git a/datapath/linux/compat/udp.c b/datapath/linux/compat/udp.c
new file mode 100644
index 0000000..a27928f
--- /dev/null
+++ b/datapath/linux/compat/udp.c
@@ -0,0 +1,43 @@
+#include <linux/version.h>
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3,16,0)
+
+#include <net/udp.h>
+
+/* Function to set UDP checksum for an IPv4 UDP packet. This is intended
+ * for the simple case like when setting the checksum for a UDP tunnel.
+ */
+void udp_set_csum(bool nocheck, struct sk_buff *skb,
+ __be32 saddr, __be32 daddr, int len)
+{
+ struct udphdr *uh = udp_hdr(skb);
+
+ if (nocheck)
+ uh->check = 0;
+ else if (skb_is_gso(skb))
+ uh->check = ~udp_v4_check(len, saddr, daddr, 0);
+ else if (skb_dst(skb) && skb_dst(skb)->dev &&
+ (skb_dst(skb)->dev->features & NETIF_F_V4_CSUM)) {
+
+ BUG_ON(skb->ip_summed == CHECKSUM_PARTIAL);
+
+ skb->ip_summed = CHECKSUM_PARTIAL;
+ skb->csum_start = skb_transport_header(skb) - skb->head;
+ skb->csum_offset = offsetof(struct udphdr, check);
+ uh->check = ~udp_v4_check(len, saddr, daddr, 0);
+ } else {
+ __wsum csum;
+
+ BUG_ON(skb->ip_summed == CHECKSUM_PARTIAL);
+
+ uh->check = 0;
+ csum = skb_checksum(skb, 0, len, 0);
+ uh->check = udp_v4_check(len, saddr, daddr, csum);
+ if (uh->check == 0)
+ uh->check = CSUM_MANGLED_0;
+
+ skb->ip_summed = CHECKSUM_UNNECESSARY;
+ }
+}
+
+#endif /* Linux version < 3.16 */
--
1.9.1
_______________________________________________
dev mailing list
[email protected]
http://openvswitch.org/mailman/listinfo/dev