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.
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])
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])
#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)
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
#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
#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;
{
#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
--- /dev/null
+#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
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
}
__be16 src_port;
__be32 saddr;
__be16 df;
- int port_min;
- int port_max;
int err;
if (unlikely(!OVS_CB(skb)->tun_key)) {
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,