From c7b22e55505bf2cef6390472a16976901fde14a2 Mon Sep 17 00:00:00 2001 From: Alexandru Ardelean Date: Sat, 6 May 2017 16:47:33 +0300 Subject: [PATCH] openvswitch: upgrade to version 2.7.0 Notes: - drop un-needed patches - bump kernel support up to 4.9 - switch from git repo to release tarball - use OVS intree kernel module ; seems that using the kernel module from the package has certain issues due to the glue/backport code that tries to adapt to many kernel versions and has a potential to mess up ; not to mention, the glue code makes the kmod a few times larger than it should be - tested on x86_64 VM Signed-off-by: Alexandru Ardelean --- net/openvswitch/Makefile | 56 ++-- ...08-add-back-old-gfp-this-node-define.patch | 19 -- ...nsure-that-thread-stacks-are-always-.patch | 75 ----- .../patches/0011-kernel-4-4-support.patch | 279 ------------------ 4 files changed, 21 insertions(+), 408 deletions(-) delete mode 100644 net/openvswitch/patches/0008-add-back-old-gfp-this-node-define.patch delete mode 100644 net/openvswitch/patches/0010-lib-ovs-thread-Ensure-that-thread-stacks-are-always-.patch delete mode 100644 net/openvswitch/patches/0011-kernel-4-4-support.patch diff --git a/net/openvswitch/Makefile b/net/openvswitch/Makefile index 2a0fcf63f5..44958e259c 100644 --- a/net/openvswitch/Makefile +++ b/net/openvswitch/Makefile @@ -12,43 +12,22 @@ include $(INCLUDE_DIR)/kernel.mk PKG_NAME:=openvswitch -PKG_RELEASE:=7 -PKG_VERSION:=2.5.0 +PKG_RELEASE:=1 +PKG_VERSION:=2.7.0 PKG_RELEASE=$(PKG_SOURCE_VERSION) PKG_LICENSE:=Apache-2.0 PKG_LICENSE_FILES:=COPYING PKG_USE_MIPS16:=0 -PKG_SOURCE_PROTO:=git -PKG_SOURCE_URL:=https://github.com/openvswitch/ovs -PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION) -PKG_SOURCE_VERSION:=22d4614ddf83988a3771fb379ea029e663b4455a -PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION).tar.gz +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz +PKG_SOURCE_URL:=http://openvswitch.org/releases/ +PKG_HASH:=e492cf08a929b4a2178b7f9b01dc4ff562f44138b547b4e942078187b2445d2e PKG_BUILD_PARALLEL:=1 PKG_FIXUP:=autoreconf PKG_INSTALL:=1 -# Upstream package supports kernels between 2.6.32 and 4.3 -# see https://github.com/openvswitch/ovs/blob/master/FAQ.md -# This list is pruned to only those kernels used in OpenWRT -# Support for kernel 4.4 is backported -SUPPORTED_KERNELS:=LINUX_3_18||LINUX_4_1||LINUX_4_3||LINUX_4_4 - -# If only kmod-openvswitch is enabled, then override default make path to only -# build and install the datapath/linux subdirectory which cuts down compilation -# time dramatically. -ifeq ($(CONFIG_PACKAGE_openvswitch-base),) - ifneq ($(CONFIG_PACKAGE_kmod-openvswitch),) - MAKE_PATH := datapath/linux - endif -endif - -# Additionally register PKG_CONFIG_DEPENDS to trigger a rebuild of the code -# base if the package selection changes. -PKG_CONFIG_DEPENDS := \ - CONFIG_PACKAGE_openvswitch-base \ - CONFIG_PACKAGE_kmod-openvswitch +SUPPORTED_KERNELS:=LINUX_3_18||LINUX_4_1||LINUX_4_3||LINUX_4_4||LINUX_4_9 include $(INCLUDE_DIR)/package.mk $(call include_mk, python-package.mk) @@ -131,10 +110,17 @@ define KernelPackage/openvswitch CATEGORY:=Kernel modules SUBMENU:=Network Support TITLE:=Open vSwitch Kernel Package - KCONFIG:=CONFIG_BRIDGE - DEPENDS:=+kmod-stp @IPV6 +kmod-gre +kmod-lib-crc32c +kmod-vxlan +kmod-nf-conntrack +kmod-nf-conntrack6 @($(SUPPORTED_KERNELS)) - FILES:= \ - $(PKG_BUILD_DIR)/datapath/linux/openvswitch.$(LINUX_KMOD_SUFFIX) + KCONFIG:= \ + CONFIG_BRIDGE \ + CONFIG_OPENVSWITCH \ + CONFIG_OPENVSWITCH_GRE=n \ + CONFIG_OPENVSWITCH_VXLAN=n \ + CONFIG_OPENVSWITCH_GENEVE=n + DEPENDS:= \ + @IPV6 +kmod-gre +kmod-lib-crc32c +kmod-mpls \ + +kmod-vxlan +kmod-nf-nat +kmod-nf-nat6 \ + @($(SUPPORTED_KERNELS)) + FILES:= $(LINUX_DIR)/net/openvswitch/openvswitch.ko AUTOLOAD:=$(call AutoLoad,21,openvswitch) endef @@ -177,10 +163,10 @@ define Package/openvswitch-base/install $(INSTALL_BIN) ./files/etc/init.d/openvswitch.init $(1)/etc/init.d/openvswitch $(INSTALL_DIR) $(1)/usr/lib/ - $(CP) $(PKG_INSTALL_DIR)/usr/lib/libofproto.so* $(1)/usr/lib/ - $(CP) $(PKG_INSTALL_DIR)/usr/lib/libopenvswitch.so* $(1)/usr/lib/ - $(CP) $(PKG_INSTALL_DIR)/usr/lib/libovsdb.so* $(1)/usr/lib/ - $(CP) $(PKG_INSTALL_DIR)/usr/lib/libsflow.so* $(1)/usr/lib/ + $(CP) $(PKG_INSTALL_DIR)/usr/lib/libofproto*.so* $(1)/usr/lib/ + $(CP) $(PKG_INSTALL_DIR)/usr/lib/libopenvswitch*.so* $(1)/usr/lib/ + $(CP) $(PKG_INSTALL_DIR)/usr/lib/libovsdb*.so* $(1)/usr/lib/ + $(CP) $(PKG_INSTALL_DIR)/usr/lib/libsflow*.so* $(1)/usr/lib/ $(INSTALL_DIR) $(1)/usr/bin/ $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/ovsdb-tool $(1)/usr/bin/ diff --git a/net/openvswitch/patches/0008-add-back-old-gfp-this-node-define.patch b/net/openvswitch/patches/0008-add-back-old-gfp-this-node-define.patch deleted file mode 100644 index ec7d325171..0000000000 --- a/net/openvswitch/patches/0008-add-back-old-gfp-this-node-define.patch +++ /dev/null @@ -1,19 +0,0 @@ -diff --git a/datapath/flow.c b/datapath/flow.c -index a7a2063..8db8041 100644 ---- a/datapath/flow.c -+++ b/datapath/flow.c -@@ -51,6 +51,14 @@ - - #include "vlan.h" - -+#ifndef GFP_THISNODE -+#ifdef CONFIG_NUMA -+#define GFP_THISNODE (__GFP_THISNODE | __GFP_NOWARN | __GFP_NORETRY) -+#else -+#define GFP_THISNODE ((__force gfp_t)0) -+#endif -+#endif -+ - u64 ovs_flow_used_time(unsigned long flow_jiffies) - { - struct timespec cur_ts; diff --git a/net/openvswitch/patches/0010-lib-ovs-thread-Ensure-that-thread-stacks-are-always-.patch b/net/openvswitch/patches/0010-lib-ovs-thread-Ensure-that-thread-stacks-are-always-.patch deleted file mode 100644 index 88f5d26158..0000000000 --- a/net/openvswitch/patches/0010-lib-ovs-thread-Ensure-that-thread-stacks-are-always-.patch +++ /dev/null @@ -1,75 +0,0 @@ -From 8147cec9ee8feea9440cf79365709ddc32ff57d5 Mon Sep 17 00:00:00 2001 -From: Alexandru Ardelean -Date: Thu, 4 Feb 2016 09:20:34 +0200 -Subject: [PATCH] lib/ovs-thread: Ensure that thread stacks are always at least - 512 kB. - -This makes a difference for libc implementations (such as musl libc) that -have a really small default pthread stack size. - -Will reference this discussion: -http://patchwork.ozlabs.org/patch/572340/ - -Reported-by: Robert McKay -Signed-off-by: Alexandru Ardelean -[blp@ovn.org made style changes] -Signed-off-by: Ben Pfaff ---- - lib/ovs-thread.c | 29 +++++++++++++++++++++++++++++ - 1 file changed, 29 insertions(+) - -diff --git a/lib/ovs-thread.c b/lib/ovs-thread.c -index 6ebda07..b0e10ee 100644 ---- a/lib/ovs-thread.c -+++ b/lib/ovs-thread.c -@@ -340,6 +340,25 @@ ovsthread_wrapper(void *aux_) - return aux.start(aux.arg); - } - -+static void -+set_min_stack_size(pthread_attr_t *attr, size_t min_stacksize) -+{ -+ size_t stacksize; -+ int error; -+ -+ error = pthread_attr_getstacksize(attr, &stacksize); -+ if (error) { -+ ovs_abort(error, "pthread_attr_getstacksize failed"); -+ } -+ -+ if (stacksize < min_stacksize) { -+ error = pthread_attr_setstacksize(attr, min_stacksize); -+ if (error) { -+ ovs_abort(error, "pthread_attr_setstacksize failed"); -+ } -+ } -+} -+ - /* Starts a thread that calls 'start(arg)'. Sets the thread's name to 'name' - * (suffixed by its ovsthread_id()). Returns the new thread's pthread_t. */ - pthread_t -@@ -358,10 +377,20 @@ ovs_thread_create(const char *name, void *(*start)(void *), void *arg) - aux->arg = arg; - ovs_strlcpy(aux->name, name, sizeof aux->name); - -- error = pthread_create(&thread, NULL, ovsthread_wrapper, aux); -+ /* Some small systems use a default stack size as small as 80 kB, but OVS -+ * requires approximately 384 kB according to the following analysis: -+ * http://openvswitch.org/pipermail/dev/2016-January/065049.html -+ * -+ * We use 512 kB to give us some margin of error. */ -+ pthread_attr_t attr; -+ pthread_attr_init(&attr); -+ set_min_stack_size(&attr, 512 * 1024); -+ -+ error = pthread_create(&thread, &attr, ovsthread_wrapper, aux); - if (error) { - ovs_abort(error, "pthread_create failed"); - } -+ pthread_attr_destroy(&attr); - return thread; - } - --- -2.1.4 - diff --git a/net/openvswitch/patches/0011-kernel-4-4-support.patch b/net/openvswitch/patches/0011-kernel-4-4-support.patch deleted file mode 100644 index 1a492e4bfc..0000000000 --- a/net/openvswitch/patches/0011-kernel-4-4-support.patch +++ /dev/null @@ -1,279 +0,0 @@ -diff --git a/acinclude.m4 b/acinclude.m4 -index 11c7787..07dd647 100644 ---- a/acinclude.m4 -+++ b/acinclude.m4 -@@ -134,10 +134,10 @@ AC_DEFUN([OVS_CHECK_LINUX], [ - AC_MSG_RESULT([$kversion]) - - if test "$version" -ge 4; then -- if test "$version" = 4 && test "$patchlevel" -le 3; then -+ if test "$version" = 4 && test "$patchlevel" -le 4; then - : # Linux 4.x - else -- AC_ERROR([Linux kernel in $KBUILD is version $kversion, but version newer than 4.3.x is not supported (please refer to the FAQ for advice)]) -+ AC_ERROR([Linux kernel in $KBUILD is version $kversion, but version newer than 4.4.x is not supported (please refer to the FAQ for advice)]) - fi - elif test "$version" = 3; then - : # Linux 3.x -diff --git a/datapath/actions.c b/datapath/actions.c -index 20413c9..719c43d 100644 ---- a/datapath/actions.c -+++ b/datapath/actions.c -@@ -706,7 +706,8 @@ static void ovs_fragment(struct vport *vport, struct sk_buff *skb, u16 mru, - skb_dst_set_noref(skb, &ovs_dst); - IPCB(skb)->frag_max_size = mru; - -- ip_do_fragment(skb->sk, skb, ovs_vport_output); -+ ip_do_fragment(NET_ARG(dev_net(ovs_dst.dev)) -+ skb->sk, skb, ovs_vport_output); - refdst_drop(orig_dst); - } else if (ethertype == htons(ETH_P_IPV6)) { - const struct nf_ipv6_ops *v6ops = nf_get_ipv6_ops(); -@@ -727,7 +728,8 @@ static void ovs_fragment(struct vport *vport, struct sk_buff *skb, u16 mru, - skb_dst_set_noref(skb, &ovs_rt.dst); - IP6CB(skb)->frag_max_size = mru; - -- v6ops->fragment(skb->sk, skb, ovs_vport_output); -+ v6ops->fragment(NET_ARG(dev_net(ovs_rt.dst.dev)) -+ skb->sk, skb, ovs_vport_output); - refdst_drop(orig_dst); - } else { - WARN_ONCE(1, "Failed fragment ->%s: eth=%04x, MRU=%d, MTU=%d.", -diff --git a/datapath/conntrack.c b/datapath/conntrack.c -index 795ed91..3b9bfba 100644 ---- a/datapath/conntrack.c -+++ b/datapath/conntrack.c -@@ -323,7 +323,7 @@ static int handle_fragments(struct net *net, struct sw_flow_key *key, - int err; - - memset(IPCB(skb), 0, sizeof(struct inet_skb_parm)); -- err = ip_defrag(skb, user); -+ err = ip_defrag(NET_ARG(net) skb, user); - if (err) - return err; - -@@ -374,7 +374,7 @@ ovs_ct_expect_find(struct net *net, const struct nf_conntrack_zone *zone, - { - struct nf_conntrack_tuple tuple; - -- if (!nf_ct_get_tuplepr(skb, skb_network_offset(skb), proto, &tuple)) -+ if (!nf_ct_get_tuplepr(skb, skb_network_offset(skb), proto, NET_ARG(net) &tuple)) - return NULL; - return __nf_ct_expect_find(net, zone, &tuple); - } -diff --git a/datapath/datapath.c b/datapath/datapath.c -index e3d3c8c..a4157f4 100644 ---- a/datapath/datapath.c -+++ b/datapath/datapath.c -@@ -96,8 +96,12 @@ static bool ovs_must_notify(struct genl_family *family, struct genl_info *info, - static void ovs_notify(struct genl_family *family, struct genl_multicast_group *grp, - struct sk_buff *skb, struct genl_info *info) - { -- genl_notify(family, skb, genl_info_net(info), -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,4,0) -+ genl_notify(family, skb, info, GROUP_ID(grp), GFP_KERNEL); -+#else -+ genl_notify(family, skb, genl_info_net(info), - info->snd_portid, GROUP_ID(grp), info->nlhdr, GFP_KERNEL); -+#endif - } - - /** -diff --git a/datapath/linux/compat/include/linux/netfilter_ipv6.h b/datapath/linux/compat/include/linux/netfilter_ipv6.h -index 3939e14..b724623 100644 ---- a/datapath/linux/compat/include/linux/netfilter_ipv6.h -+++ b/datapath/linux/compat/include/linux/netfilter_ipv6.h -@@ -13,7 +13,7 @@ - * the callback parameter needs to be in the form that older kernels accept. - * We don't backport the other ipv6_ops as they're currently unused by OVS. */ - struct ovs_nf_ipv6_ops { -- int (*fragment)(struct sock *sk, struct sk_buff *skb, -+ int (*fragment)(NET_ARG(net) struct sock *sk, struct sk_buff *skb, - int (*output)(OVS_VPORT_OUTPUT_PARAMS)); - }; - #define nf_ipv6_ops ovs_nf_ipv6_ops -diff --git a/datapath/linux/compat/include/net/ip.h b/datapath/linux/compat/include/net/ip.h -index cd87bcc..b749301 100644 ---- a/datapath/linux/compat/include/net/ip.h -+++ b/datapath/linux/compat/include/net/ip.h -@@ -66,8 +66,20 @@ static inline unsigned int rpl_ip_skb_dst_mtu(const struct sk_buff *skb) - #define ip_skb_dst_mtu rpl_ip_skb_dst_mtu - #endif /* HAVE_IP_SKB_DST_MTU */ - -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,4,0) -+#define NET_PARAM(x) struct net *x, -+#define NET_ARG(x) x, -+#define NET_DEV_NET(x) dev_net(x) -+#define NET_DECLARE_INIT(x,y) -+#else -+#define NET_PARAM(x) -+#define NET_ARG(x) -+#define NET_DEV_NET(x) -+#define NET_DECLARE_INIT(x,y) struct net *x = y; -+#endif -+ - #ifdef HAVE_IP_FRAGMENT_TAKES_SOCK --#define OVS_VPORT_OUTPUT_PARAMS struct sock *sock, struct sk_buff *skb -+#define OVS_VPORT_OUTPUT_PARAMS NET_PARAM(net) struct sock *sock, struct sk_buff *skb - #else - #define OVS_VPORT_OUTPUT_PARAMS struct sk_buff *skb - #endif -@@ -89,12 +101,13 @@ static inline bool ip_defrag_user_in_between(u32 user, - #endif /* < v4.2 */ - - #ifndef HAVE_IP_DO_FRAGMENT --static inline int rpl_ip_do_fragment(struct sock *sk, struct sk_buff *skb, -+static inline int rpl_ip_do_fragment(NET_PARAM(net) struct sock *sk, struct sk_buff *skb, - int (*output)(OVS_VPORT_OUTPUT_PARAMS)) - { - unsigned int mtu = ip_skb_dst_mtu(skb); - struct iphdr *iph = ip_hdr(skb); - struct rtable *rt = skb_rtable(skb); - struct net_device *dev = rt->dst.dev; -+ NET_DECLARE_INIT(net, dev_net(dev)); - - if (unlikely(((iph->frag_off & htons(IP_DF)) && !skb->ignore_df) || -@@ -102,7 +115,7 @@ static inline int rpl_ip_do_fragment(struct sock *sk, struct sk_buff *skb, - IPCB(skb)->frag_max_size > mtu))) { - - pr_warn("Dropping packet in ip_do_fragment()\n"); -- IP_INC_STATS(dev_net(dev), IPSTATS_MIB_FRAGFAILS); -+ IP_INC_STATS(net, IPSTATS_MIB_FRAGFAILS); - kfree_skb(skb); - return -EMSGSIZE; - } -@@ -116,8 +129,7 @@ static inline int rpl_ip_do_fragment(struct sock *sk, struct sk_buff *skb, - #define ip_do_fragment rpl_ip_do_fragment - #endif /* IP_DO_FRAGMENT */ - --int rpl_ip_defrag(struct sk_buff *skb, u32 user); --#define ip_defrag rpl_ip_defrag -+int rpl_ip_defrag(NET_PARAM(net) struct sk_buff *skb, u32 user); - - int __init rpl_ipfrag_init(void); - void rpl_ipfrag_fini(void); -@@ -127,14 +139,15 @@ void rpl_ipfrag_fini(void); - * ("inet: frag: Always orphan skbs inside ip_defrag()"), but it should be - * always included in kernels 4.5+. */ - #if LINUX_VERSION_CODE < KERNEL_VERSION(4,5,0) --static inline int rpl_ip_defrag(struct sk_buff *skb, u32 user) -+static inline int rpl_ip_defrag(NET_PARAM(net) struct sk_buff *skb, u32 user) - { - skb_orphan(skb); -- return ip_defrag(skb, user); -+ return ip_defrag(NET_ARG(net) skb, user); - } --#define ip_defrag rpl_ip_defrag - #endif - -+#define ip_defrag rpl_ip_defrag -+ - static inline int rpl_ipfrag_init(void) { return 0; } - static inline void rpl_ipfrag_fini(void) { } - #endif /* HAVE_CORRECT_MRU_HANDLING && OVS_FRAGMENT_BACKPORT */ -diff --git a/datapath/linux/compat/include/net/ip6_tunnel.h b/datapath/linux/compat/include/net/ip6_tunnel.h -index ce65087..eacf9ca 100644 ---- a/datapath/linux/compat/include/net/ip6_tunnel.h -+++ b/datapath/linux/compat/include/net/ip6_tunnel.h -@@ -17,11 +17,15 @@ static inline void ip6tunnel_xmit(struct sock *sk, struct sk_buff *skb, - - pkt_len = skb->len - skb_inner_network_offset(skb); - /* TODO: Fix GSO for ipv6 */ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,4,0) -+ err = ip6_local_out(dev_net(dev), sk, skb); -+#else - #ifdef HAVE_IP6_LOCAL_OUT_SK - err = ip6_local_out_sk(sk, skb); - #else - err = ip6_local_out(skb); - #endif -+#endif /* >= kernel 4.4 */ - if (net_xmit_eval(err) != 0) - pkt_len = net_xmit_eval(err); - else -diff --git a/datapath/linux/compat/include/net/vxlan.h b/datapath/linux/compat/include/net/vxlan.h -index b50cd17..230f3ad 100644 ---- a/datapath/linux/compat/include/net/vxlan.h -+++ b/datapath/linux/compat/include/net/vxlan.h -@@ -218,10 +218,20 @@ struct vxlan_dev { - struct net_device *rpl_vxlan_dev_create(struct net *net, const char *name, - u8 name_assign_type, struct vxlan_config *conf); - -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,4,0) -+static inline __be16 vxlan_dev_dst_port(struct vxlan_dev *vxlan, -+ unsigned short family) -+{ -+ if (family == AF_INET6) -+ return inet_sk(vxlan->vn6_sock->sock->sk)->inet_sport; -+ return inet_sk(vxlan->vn4_sock->sock->sk)->inet_sport; -+} -+#else - static inline __be16 vxlan_dev_dst_port(struct vxlan_dev *vxlan) - { - return inet_sport(vxlan->vn_sock->sock->sk); - } -+#endif - - static inline netdev_features_t vxlan_features_check(struct sk_buff *skb, - netdev_features_t features) -diff --git a/datapath/linux/compat/ip_fragment.c b/datapath/linux/compat/ip_fragment.c -index cf2daaa..e168196 100644 ---- a/datapath/linux/compat/ip_fragment.c -+++ b/datapath/linux/compat/ip_fragment.c -@@ -674,11 +674,11 @@ out_fail: - } - - /* Process an incoming IP datagram fragment. */ --int rpl_ip_defrag(struct sk_buff *skb, u32 user) -+int rpl_ip_defrag(NET_ARG(net) struct sk_buff *skb, u32 user) - { - struct net_device *dev = skb->dev ? : skb_dst(skb)->dev; - int vif = vrf_master_ifindex_rcu(dev); -- struct net *net = dev_net(dev); -+ NET_DECLARE_INIT(net, dev_net(dev)); - struct ipq *qp; - - IP_INC_STATS_BH(net, IPSTATS_MIB_REASMREQDS); -diff --git a/datapath/linux/compat/stt.c b/datapath/linux/compat/stt.c -index eb397e8..5ea3c52 100644 ---- a/datapath/linux/compat/stt.c -+++ b/datapath/linux/compat/stt.c -@@ -1450,7 +1450,11 @@ static void clean_percpu(struct work_struct *work) - } - - #ifdef HAVE_NF_HOOKFN_ARG_OPS -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,4,0) -+#define FIRST_PARAM void *priv -+#else - #define FIRST_PARAM const struct nf_hook_ops *ops -+#endif /* >= kernel 4.4 */ - #else - #define FIRST_PARAM unsigned int hooknum - #endif -@@ -1498,7 +1502,9 @@ static unsigned int nf_ip_hook(FIRST_PARAM, struct sk_buff *skb, LAST_PARAM) - - static struct nf_hook_ops nf_hook_ops __read_mostly = { - .hook = nf_ip_hook, -+#if LINUX_VERSION_CODE < KERNEL_VERSION(4,4,0) - .owner = THIS_MODULE, -+#endif - .pf = NFPROTO_IPV4, - .hooknum = NF_INET_LOCAL_IN, - .priority = INT_MAX, -diff --git a/datapath/vport-vxlan.c b/datapath/vport-vxlan.c -index c05f5d4..3cbb568 100644 ---- a/datapath/vport-vxlan.c -+++ b/datapath/vport-vxlan.c -@@ -153,7 +153,12 @@ static int vxlan_get_egress_tun_info(struct vport *vport, struct sk_buff *skb, - { - struct vxlan_dev *vxlan = netdev_priv(vport->dev); - struct net *net = ovs_dp_get_net(vport->dp); -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,4,0) -+ unsigned short family = ip_tunnel_info_af(upcall->egress_tun_info); -+ __be16 dst_port = vxlan_dev_dst_port(vxlan, family); -+#else - __be16 dst_port = vxlan_dev_dst_port(vxlan); -+#endif - __be16 src_port; - int port_min; - int port_max;