Some of code is backported from following commit.
commit 13dd4a9738e99684a56b10ce2f1a5ee2d2ec2f9f
Author: Joe Stringer <[email protected]>
Date: Tue Mar 24 16:16:18 2015 -0700
compat: Fix RHEL7 build.
Tested against 3.10.0-229.el7.x86_64.
----------8<--------
Reported-by: Alex Wang <[email protected]>
Signed-off-by: Pravin B Shelar <[email protected]>
---
acinclude.m4 | 46 ++++++++++++++++++++++
datapath/compat.h | 6 +-
datapath/linux/Modules.mk | 1 +
datapath/linux/compat/genetlink-openvswitch.c | 2 +-
datapath/linux/compat/include/net/genetlink.h | 2 +-
datapath/linux/compat/include/net/ip_tunnels.h | 4 ++
datapath/linux/compat/include/net/udp.h | 49 ++++++++++++++++++++++++
datapath/linux/compat/include/net/vxlan.h | 6 +-
datapath/vport-vxlan.c | 5 +--
9 files changed, 109 insertions(+), 12 deletions(-)
create mode 100644 datapath/linux/compat/include/net/udp.h
diff --git a/acinclude.m4 b/acinclude.m4
index ee13e0e..992bd53 100644
--- a/acinclude.m4
+++ b/acinclude.m4
@@ -212,6 +212,37 @@ AC_DEFUN([OVS_GREP_IFELSE], [
fi
])
+dnl OVS_FIND_FIELD_IFELSE(FILE, STRUCTURE, REGEX, [IF-MATCH], [IF-NO-MATCH])
+dnl
+dnl Looks for STRUCTURE in FILE. If it is found, greps for REGEX within the
+dnl structure definition. If this is successful, runs IF-MATCH, otherwise
+dnl IF_NO_MATCH. If IF-MATCH is empty then it defines to
+dnl OVS_DEFINE(HAVE_<STRUCTURE>_WITH_<REGEX>), with <STRUCTURE> and <REGEX>
+dnl translated to uppercase.
+AC_DEFUN([OVS_FIND_FIELD_IFELSE], [
+ AC_MSG_CHECKING([whether $2 has member $3 in $1])
+ if test -f $1; then
+ awk '/$2.{/,/^}/' $1 2>/dev/null | grep '$3'
+ status=$?
+ case $status in
+ 0)
+ AC_MSG_RESULT([yes])
+ m4_if([$4], [],
[OVS_DEFINE([HAVE_]m4_toupper([$2])[_WITH_]m4_toupper([$3]))], [$4])
+ ;;
+ 1)
+ AC_MSG_RESULT([no])
+ $5
+ ;;
+ *)
+ AC_MSG_ERROR([grep exited with status $status])
+ ;;
+ esac
+ else
+ AC_MSG_RESULT([file not found])
+ $5
+ fi
+])
+
dnl OVS_DEFINE(NAME)
dnl
dnl Defines NAME to 1 in kcompat.h.
@@ -316,10 +347,19 @@ AC_DEFUN([OVS_CHECK_LINUX_COMPAT], [
OVS_GREP_IFELSE([$KSRC/include/net/genetlink.h], [parallel_ops])
OVS_GREP_IFELSE([$KSRC/include/net/genetlink.h], [genlmsg_new_unicast])
+ OVS_GREP_IFELSE([$KSRC/include/net/genetlink.h], [genl_notify.*genl_family],
+ [OVS_DEFINE([HAVE_GENL_NOTIFY_TAKES_FAMILY])])
+
+ OVS_FIND_FIELD_IFELSE([$KSRC/include/net/genetlink.h],
+ [genl_multicast_group], [id])
+
OVS_GREP_IFELSE([$KSRC/include/net/gre.h], [gre_cisco_register])
OVS_GREP_IFELSE([$KSRC/include/net/gre.h], [gre_handle_offloads])
OVS_GREP_IFELSE([$KSRC/include/net/ip_tunnels.h], [iptunnel_xmit.*net],
[OVS_DEFINE([HAVE_IPTUNNEL_XMIT_NET])])
+ OVS_GREP_IFELSE([$KSRC/include/net/ip_tunnels.h], [iptunnel_xmit.*sock],
+ [OVS_DEFINE([HAVE_IPTUNNEL_XMIT_SOCK])])
+
OVS_GREP_IFELSE([$KSRC/include/net/ipv6.h], [IP6_FH_F_SKIP_RH])
OVS_GREP_IFELSE([$KSRC/include/net/netlink.h], [nla_get_be16])
OVS_GREP_IFELSE([$KSRC/include/net/netlink.h], [nla_put_be16])
@@ -327,7 +367,13 @@ AC_DEFUN([OVS_CHECK_LINUX_COMPAT], [
OVS_GREP_IFELSE([$KSRC/include/net/netlink.h], [nla_put_be64])
OVS_GREP_IFELSE([$KSRC/include/net/netlink.h], [nla_find_nested])
OVS_GREP_IFELSE([$KSRC/include/net/vxlan.h], [vxlan_xmit_skb])
+ OVS_GREP_IFELSE([$KSRC/include/net/vxlan.h], [vxlan_xmit_skb.*net],
+ [OVS_DEFINE([HAVE_VXLAN_XMIT_SKB_NET])])
+ OVS_GREP_IFELSE([$KSRC/include/net/udp.h], [udp_flow_src_port],
+ [OVS_GREP_IFELSE([$KSRC/include/net/udp.h],
[inet_get_local_port_range(net],
+ [OVS_DEFINE([HAVE_UDP_FLOW_SRC_PORT])])])
+
OVS_GREP_IFELSE([$KSRC/include/net/sctp/checksum.h], [sctp_compute_cksum])
OVS_GREP_IFELSE([$KSRC/include/linux/if_vlan.h], [ADD_ALL_VLANS_CMD],
diff --git a/datapath/compat.h b/datapath/compat.h
index f38d38c..d7447d2 100644
--- a/datapath/compat.h
+++ b/datapath/compat.h
@@ -25,10 +25,10 @@
#include <net/route.h>
#include <net/xfrm.h>
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,13,0)
-#define GROUP_ID(grp) 0
-#else
+#ifdef HAVE_GENL_MULTICAST_GROUP_WITH_ID
#define GROUP_ID(grp) ((grp)->id)
+#else
+#define GROUP_ID(grp) 0
#endif
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,36)
diff --git a/datapath/linux/Modules.mk b/datapath/linux/Modules.mk
index 224eb02..2044b7b 100644
--- a/datapath/linux/Modules.mk
+++ b/datapath/linux/Modules.mk
@@ -71,5 +71,6 @@ openvswitch_headers += \
linux/compat/include/net/net_namespace.h \
linux/compat/include/net/netlink.h \
linux/compat/include/net/sock.h \
+ linux/compat/include/net/udp.h \
linux/compat/include/net/vxlan.h \
linux/compat/include/net/sctp/checksum.h
diff --git a/datapath/linux/compat/genetlink-openvswitch.c
b/datapath/linux/compat/genetlink-openvswitch.c
index 08f0fab..cff58b8 100644
--- a/datapath/linux/compat/genetlink-openvswitch.c
+++ b/datapath/linux/compat/genetlink-openvswitch.c
@@ -1,7 +1,7 @@
#include <net/genetlink.h>
#include <linux/version.h>
-#if LINUX_VERSION_CODE < KERNEL_VERSION(3,13,0)
+#ifndef HAVE_GENL_NOTIFY_TAKES_FAMILY
#undef genl_notify
diff --git a/datapath/linux/compat/include/net/genetlink.h
b/datapath/linux/compat/include/net/genetlink.h
index 9b2aa5b..51b7ce5 100644
--- a/datapath/linux/compat/include/net/genetlink.h
+++ b/datapath/linux/compat/include/net/genetlink.h
@@ -17,7 +17,7 @@
#define portid pid
#endif
-#if LINUX_VERSION_CODE < KERNEL_VERSION(3,13,0)
+#ifndef HAVE_GENL_NOTIFY_TAKES_FAMILY
struct rpl_genl_family {
struct genl_family compat_family;
unsigned int id;
diff --git a/datapath/linux/compat/include/net/ip_tunnels.h
b/datapath/linux/compat/include/net/ip_tunnels.h
index 4fc4fb4..ba7ef08 100644
--- a/datapath/linux/compat/include/net/ip_tunnels.h
+++ b/datapath/linux/compat/include/net/ip_tunnels.h
@@ -21,8 +21,12 @@ static inline int rpl_iptunnel_xmit(struct rtable *rt,
#ifdef HAVE_IPTUNNEL_XMIT_NET
return iptunnel_xmit(NULL, rt, skb, src, dst, proto, tos, ttl, df);
#else
+#ifdef HAVE_IPTUNNEL_XMIT_SOCK
+ return iptunnel_xmit(NULL, rt, skb, src, dst, proto, tos, ttl, df);
+#else
return iptunnel_xmit(rt, skb, src, dst, proto, tos, ttl, df, xnet);
#endif
+#endif
}
#define iptunnel_xmit rpl_iptunnel_xmit
diff --git a/datapath/linux/compat/include/net/udp.h
b/datapath/linux/compat/include/net/udp.h
new file mode 100644
index 0000000..94f1cb0
--- /dev/null
+++ b/datapath/linux/compat/include/net/udp.h
@@ -0,0 +1,49 @@
+#ifndef __NET_UDP_WRAPPER_H
+#define __NET_UDP_WRAPPER_H 1
+
+#include <linux/version.h>
+
+#ifdef inet_get_local_port_range
+/* RHEL7 backports udp_flow_src_port() using an older version of
+ * inet_get_local_port_range(). */
+#undef inet_get_local_port_range
+#include_next <net/udp.h>
+#define inet_get_local_port_range rpl_inet_get_local_port_range
+#else
+#include_next <net/udp.h>
+#endif
+
+#ifndef HAVE_UDP_FLOW_SRC_PORT
+static inline __be16 rpl_udp_flow_src_port(struct net *net, struct sk_buff
*skb,
+ int min, int max, bool use_eth)
+{
+ u32 hash;
+
+ if (min >= max) {
+ /* Use default range */
+ inet_get_local_port_range(net, &min, &max);
+ }
+
+ hash = skb_get_hash(skb);
+ if (unlikely(!hash) && use_eth) {
+ /* Can't find a normal hash, caller has indicated an Ethernet
+ * packet so use that to compute a hash.
+ */
+ hash = jhash(skb->data, 2 * ETH_ALEN,
+ (__force u32) skb->protocol);
+ }
+
+ /* Since this is being sent on the wire obfuscate hash a bit
+ * to minimize possbility that any useful information to an
+ * attacker is leaked. Only upper 16 bits are relevant in the
+ * computation for 16 bit port value.
+ */
+ hash ^= hash << 16;
+
+ return htons((((u64) hash * (max - min)) >> 32) + min);
+}
+
+#define udp_flow_src_port rpl_udp_flow_src_port
+#endif
+
+#endif
diff --git a/datapath/linux/compat/include/net/vxlan.h
b/datapath/linux/compat/include/net/vxlan.h
index 23877ad..be249a3 100644
--- a/datapath/linux/compat/include/net/vxlan.h
+++ b/datapath/linux/compat/include/net/vxlan.h
@@ -19,11 +19,11 @@ static inline int rpl_vxlan_xmit_skb(struct vxlan_sock *vs,
kfree_skb(skb);
return -ENOSYS;
}
-#ifndef HAVE_IPTUNNEL_XMIT_NET
- return vxlan_xmit_skb(vs, rt, skb, src, dst, tos, ttl, df,
+#ifdef HAVE_VXLAN_XMIT_SKB_NET
+ return vxlan_xmit_skb(NULL, vs, rt, skb, src, dst, tos, ttl, df,
src_port, dst_port, vni);
#else
- return vxlan_xmit_skb(NULL, vs, rt, skb, src, dst, tos, ttl, df,
+ return vxlan_xmit_skb(vs, rt, skb, src, dst, tos, ttl, df,
src_port, dst_port, vni);
#endif
}
diff --git a/datapath/vport-vxlan.c b/datapath/vport-vxlan.c
index cc9477d..1b4333c 100644
--- a/datapath/vport-vxlan.c
+++ b/datapath/vport-vxlan.c
@@ -146,8 +146,6 @@ static int vxlan_tnl_send(struct vport *vport, struct
sk_buff *skb)
__be16 src_port;
__be32 saddr;
__be16 df;
- int port_min;
- int port_max;
int err;
if (unlikely(!OVS_CB(skb)->tun_key)) {
@@ -173,8 +171,7 @@ static int vxlan_tnl_send(struct vport *vport, struct
sk_buff *skb)
skb->local_df = 1;
- inet_get_local_port_range(net, &port_min, &port_max);
- src_port = vxlan_src_port(port_min, port_max, skb);
+ src_port = udp_flow_src_port(net, skb, 0, 0, true);
err = vxlan_xmit_skb(vxlan_port->vs, rt, skb,
saddr, OVS_CB(skb)->tun_key->ipv4_dst,
--
1.7.1
_______________________________________________
dev mailing list
[email protected]
http://openvswitch.org/mailman/listinfo/dev