diff --git a/patches/lede/0032-generic-vxlan-backport-support-for-VXLAN-over-link-local-IPv6.patch b/patches/lede/0032-generic-vxlan-backport-support-for-VXLAN-over-link-local-IPv6.patch
new file mode 100644
index 0000000000000000000000000000000000000000..43bbf1054a1869a0760ea33f5ec642f97af8d374
--- /dev/null
+++ b/patches/lede/0032-generic-vxlan-backport-support-for-VXLAN-over-link-local-IPv6.patch
@@ -0,0 +1,436 @@
+From: Matthias Schiffer <mschiffer@universe-factory.net>
+Date: Wed, 21 Jun 2017 00:54:57 +0200
+Subject: generic: vxlan: backport support for VXLAN over link-local IPv6
+
+diff --git a/target/linux/generic/patches-4.4/075-0001-vxlan-improve-validation-of-address-family-configura.patch b/target/linux/generic/patches-4.4/075-0001-vxlan-improve-validation-of-address-family-configura.patch
+new file mode 100644
+index 0000000000000000000000000000000000000000..439eb5d0f769f1cde23ff4deacc80728e82605f2
+--- /dev/null
++++ b/target/linux/generic/patches-4.4/075-0001-vxlan-improve-validation-of-address-family-configura.patch
+@@ -0,0 +1,68 @@
++From 434a1bb54b24b538f81d7945128b7ca25976d19b Mon Sep 17 00:00:00 2001
++Message-Id: <434a1bb54b24b538f81d7945128b7ca25976d19b.1498005061.git.mschiffer@universe-factory.net>
++From: Matthias Schiffer <mschiffer@universe-factory.net>
++Date: Mon, 19 Jun 2017 10:03:57 +0200
++Subject: [PATCH 1/4] vxlan: improve validation of address family configuration
++
++Address families of source and destination addresses must match, and
++changelink operations can't change the address family.
++
++In addition, always use the VXLAN_F_IPV6 to check if a VXLAN device uses
++IPv4 or IPv6.
++
++Signed-off-by: Matthias Schiffer <mschiffer@universe-factory.net>
++Signed-off-by: David S. Miller <davem@davemloft.net>
++[Matthias Schiffer: rebase to v4.4.y]
++---
++ drivers/net/vxlan.c | 23 +++++++++++++++--------
++ 1 file changed, 15 insertions(+), 8 deletions(-)
++
++--- a/drivers/net/vxlan.c
+++++ b/drivers/net/vxlan.c
++@@ -2784,12 +2784,20 @@ static int vxlan_dev_configure(struct ne
++ 
++ 	memcpy(&dst->remote_ip, &conf->remote_ip, sizeof(conf->remote_ip));
++ 
++-	/* Unless IPv6 is explicitly requested, assume IPv4 */
++-	if (!dst->remote_ip.sa.sa_family)
+++	if (!dst->remote_ip.sa.sa_family && !conf->saddr.sa.sa_family) {
+++		/* Unless IPv6 is explicitly requested, assume IPv4 */
++ 		dst->remote_ip.sa.sa_family = AF_INET;
+++		conf->saddr.sa.sa_family = AF_INET;
+++	} else if (!dst->remote_ip.sa.sa_family) {
+++		dst->remote_ip.sa.sa_family = conf->saddr.sa.sa_family;
+++	} else if (!conf->saddr.sa.sa_family) {
+++		conf->saddr.sa.sa_family = dst->remote_ip.sa.sa_family;
+++	}
+++
+++	if (conf->saddr.sa.sa_family != dst->remote_ip.sa.sa_family)
+++		return -EINVAL;
++ 
++-	if (dst->remote_ip.sa.sa_family == AF_INET6 ||
++-	    vxlan->cfg.saddr.sa.sa_family == AF_INET6) {
+++	if (conf->saddr.sa.sa_family == AF_INET6) {
++ 		if (!IS_ENABLED(CONFIG_IPV6))
++ 			return -EPFNOSUPPORT;
++ 		use_ipv6 = true;
++@@ -2843,11 +2851,9 @@ static int vxlan_dev_configure(struct ne
++ 
++ 	list_for_each_entry(tmp, &vn->vxlan_list, next) {
++ 		if (tmp->cfg.vni == conf->vni &&
++-		    (tmp->default_dst.remote_ip.sa.sa_family == AF_INET6 ||
++-		     tmp->cfg.saddr.sa.sa_family == AF_INET6) == use_ipv6 &&
++ 		    tmp->cfg.dst_port == vxlan->cfg.dst_port &&
++-		    (tmp->flags & VXLAN_F_RCV_FLAGS) ==
++-		    (vxlan->flags & VXLAN_F_RCV_FLAGS))
+++		    (tmp->flags & (VXLAN_F_RCV_FLAGS | VXLAN_F_IPV6)) ==
+++		    (vxlan->flags & (VXLAN_F_RCV_FLAGS | VXLAN_F_IPV6)))
++ 		return -EEXIST;
++ 	}
++ 
++@@ -2915,6 +2921,7 @@ static int vxlan_newlink(struct net *src
++ 
++ 	if (data[IFLA_VXLAN_GROUP]) {
++ 		conf.remote_ip.sin.sin_addr.s_addr = nla_get_in_addr(data[IFLA_VXLAN_GROUP]);
+++		conf.remote_ip.sa.sa_family = AF_INET;
++ 	} else if (data[IFLA_VXLAN_GROUP6]) {
++ 		if (!IS_ENABLED(CONFIG_IPV6))
++ 			return -EPFNOSUPPORT;
+diff --git a/target/linux/generic/patches-4.4/075-0002-vxlan-check-valid-combinations-of-address-scopes.patch b/target/linux/generic/patches-4.4/075-0002-vxlan-check-valid-combinations-of-address-scopes.patch
+new file mode 100644
+index 0000000000000000000000000000000000000000..abf9b8a0eae88aa5a64be5cc82a6827d4d562c55
+--- /dev/null
++++ b/target/linux/generic/patches-4.4/075-0002-vxlan-check-valid-combinations-of-address-scopes.patch
+@@ -0,0 +1,84 @@
++From 8956b9db43347a51e88dddc3c08fb88ff60dea54 Mon Sep 17 00:00:00 2001
++Message-Id: <8956b9db43347a51e88dddc3c08fb88ff60dea54.1498005061.git.mschiffer@universe-factory.net>
++In-Reply-To: <434a1bb54b24b538f81d7945128b7ca25976d19b.1498005061.git.mschiffer@universe-factory.net>
++References: <434a1bb54b24b538f81d7945128b7ca25976d19b.1498005061.git.mschiffer@universe-factory.net>
++From: Matthias Schiffer <mschiffer@universe-factory.net>
++Date: Mon, 19 Jun 2017 10:03:58 +0200
++Subject: [PATCH 2/4] vxlan: check valid combinations of address scopes
++
++* Multicast addresses are never valid as local address
++* Link-local IPv6 unicast addresses may only be used as remote when the
++  local address is link-local as well
++* Don't allow link-local IPv6 local/remote addresses without interface
++
++We also store in the flags field if link-local addresses are used for the
++follow-up patches that actually make VXLAN over link-local IPv6 work.
++
++Signed-off-by: Matthias Schiffer <mschiffer@universe-factory.net>
++Signed-off-by: David S. Miller <davem@davemloft.net>
++[Matthias Schiffer: rebase to v4.4.y]
++---
++ drivers/net/vxlan.c | 29 +++++++++++++++++++++++++++++
++ include/net/vxlan.h |  1 +
++ 2 files changed, 30 insertions(+)
++
++--- a/drivers/net/vxlan.c
+++++ b/drivers/net/vxlan.c
++@@ -2797,11 +2797,35 @@ static int vxlan_dev_configure(struct ne
++ 	if (conf->saddr.sa.sa_family != dst->remote_ip.sa.sa_family)
++ 		return -EINVAL;
++ 
+++	if (vxlan_addr_multicast(&conf->saddr))
+++		return -EINVAL;
+++
++ 	if (conf->saddr.sa.sa_family == AF_INET6) {
++ 		if (!IS_ENABLED(CONFIG_IPV6))
++ 			return -EPFNOSUPPORT;
++ 		use_ipv6 = true;
++ 		vxlan->flags |= VXLAN_F_IPV6;
+++
+++		if (!(conf->flags & VXLAN_F_COLLECT_METADATA)) {
+++			int local_type =
+++				ipv6_addr_type(&conf->saddr.sin6.sin6_addr);
+++			int remote_type =
+++				ipv6_addr_type(&dst->remote_ip.sin6.sin6_addr);
+++
+++			if (local_type & IPV6_ADDR_LINKLOCAL) {
+++				if (!(remote_type & IPV6_ADDR_LINKLOCAL) &&
+++				    (remote_type != IPV6_ADDR_ANY))
+++					return -EINVAL;
+++
+++				vxlan->flags |= VXLAN_F_IPV6_LINKLOCAL;
+++			} else {
+++				if (remote_type ==
+++				    (IPV6_ADDR_UNICAST | IPV6_ADDR_LINKLOCAL))
+++					return -EINVAL;
+++
+++				vxlan->flags &= ~VXLAN_F_IPV6_LINKLOCAL;
+++			}
+++		}
++ 	}
++ 
++ 	if (conf->remote_ifindex) {
++@@ -2827,6 +2851,11 @@ static int vxlan_dev_configure(struct ne
++ 			dev->mtu = lowerdev->mtu - (use_ipv6 ? VXLAN6_HEADROOM : VXLAN_HEADROOM);
++ 
++ 		needed_headroom = lowerdev->hard_header_len;
+++	} else {
+++#if IS_ENABLED(CONFIG_IPV6)
+++		if (vxlan->flags & VXLAN_F_IPV6_LINKLOCAL)
+++			return -EINVAL;
+++#endif
++ 	}
++ 
++ 	if (conf->mtu) {
++--- a/include/net/vxlan.h
+++++ b/include/net/vxlan.h
++@@ -185,6 +185,7 @@ struct vxlan_dev {
++ #define VXLAN_F_GBP			0x800
++ #define VXLAN_F_REMCSUM_NOPARTIAL	0x1000
++ #define VXLAN_F_COLLECT_METADATA	0x2000
+++#define VXLAN_F_IPV6_LINKLOCAL		0x8000
++ 
++ /* Flags that are used in the receive path. These flags must match in
++  * order for a socket to be shareable
+diff --git a/target/linux/generic/patches-4.4/075-0003-vxlan-fix-snooping-for-link-local-IPv6-addresses.patch b/target/linux/generic/patches-4.4/075-0003-vxlan-fix-snooping-for-link-local-IPv6-addresses.patch
+new file mode 100644
+index 0000000000000000000000000000000000000000..5ebbce6e0682fff11b0d86c8df781a5c2fab5125
+--- /dev/null
++++ b/target/linux/generic/patches-4.4/075-0003-vxlan-fix-snooping-for-link-local-IPv6-addresses.patch
+@@ -0,0 +1,88 @@
++From e3bdb4bc6c4020e90c1bbafd91645ff3ae8966b9 Mon Sep 17 00:00:00 2001
++Message-Id: <e3bdb4bc6c4020e90c1bbafd91645ff3ae8966b9.1498005061.git.mschiffer@universe-factory.net>
++In-Reply-To: <434a1bb54b24b538f81d7945128b7ca25976d19b.1498005061.git.mschiffer@universe-factory.net>
++References: <434a1bb54b24b538f81d7945128b7ca25976d19b.1498005061.git.mschiffer@universe-factory.net>
++From: Matthias Schiffer <mschiffer@universe-factory.net>
++Date: Mon, 19 Jun 2017 10:03:59 +0200
++Subject: [PATCH 3/4] vxlan: fix snooping for link-local IPv6 addresses
++
++If VXLAN is run over link-local IPv6 addresses, it is necessary to store
++the ifindex in the FDB entries. Otherwise, the used interface is undefined
++and unicast communication will most likely fail.
++
++Support for link-local IPv4 addresses should be possible as well, but as
++the semantics aren't as well defined as for IPv6, and there doesn't seem to
++be much interest in having the support, it's not implemented for now.
++
++Signed-off-by: Matthias Schiffer <mschiffer@universe-factory.net>
++Signed-off-by: David S. Miller <davem@davemloft.net>
++[Matthias Schiffer: rebase to v4.4.y]
++---
++ drivers/net/vxlan.c | 20 +++++++++++++++-----
++ 1 file changed, 15 insertions(+), 5 deletions(-)
++
++--- a/drivers/net/vxlan.c
+++++ b/drivers/net/vxlan.c
++@@ -947,16 +947,25 @@ out:
++  * Return true if packet is bogus and should be dropped.
++  */
++ static bool vxlan_snoop(struct net_device *dev,
++-			union vxlan_addr *src_ip, const u8 *src_mac)
+++			union vxlan_addr *src_ip, const u8 *src_mac,
+++			u32 src_ifindex)
++ {
++ 	struct vxlan_dev *vxlan = netdev_priv(dev);
++ 	struct vxlan_fdb *f;
+++	u32 ifindex = 0;
+++
+++#if IS_ENABLED(CONFIG_IPV6)
+++	if (src_ip->sa.sa_family == AF_INET6 &&
+++	    (ipv6_addr_type(&src_ip->sin6.sin6_addr) & IPV6_ADDR_LINKLOCAL))
+++		ifindex = src_ifindex;
+++#endif
++ 
++ 	f = vxlan_find_mac(vxlan, src_mac);
++ 	if (likely(f)) {
++ 		struct vxlan_rdst *rdst = first_remote_rcu(f);
++ 
++-		if (likely(vxlan_addr_equal(&rdst->remote_ip, src_ip)))
+++		if (likely(vxlan_addr_equal(&rdst->remote_ip, src_ip) &&
+++			   rdst->remote_ifindex == ifindex))
++ 			return false;
++ 
++ 		/* Don't migrate static entries, drop packets */
++@@ -982,7 +991,7 @@ static bool vxlan_snoop(struct net_devic
++ 					 NLM_F_EXCL|NLM_F_CREATE,
++ 					 vxlan->cfg.dst_port,
++ 					 vxlan->default_dst.remote_vni,
++-					 0, NTF_SELF);
+++					 ifindex, NTF_SELF);
++ 		spin_unlock(&vxlan->hash_lock);
++ 	}
++ 
++@@ -1157,6 +1166,7 @@ static void vxlan_rcv(struct vxlan_sock
++ 	struct vxlan_dev *vxlan;
++ 	struct pcpu_sw_netstats *stats;
++ 	union vxlan_addr saddr;
+++	u32 ifindex = skb->dev->ifindex;
++ 	int err = 0;
++ 
++ 	/* For flow based devices, map all packets to VNI 0 */
++@@ -1196,7 +1206,7 @@ static void vxlan_rcv(struct vxlan_sock
++ 	}
++ 
++ 	if ((vxlan->flags & VXLAN_F_LEARN) &&
++-	    vxlan_snoop(skb->dev, &saddr, eth_hdr(skb)->h_source))
+++	    vxlan_snoop(skb->dev, &saddr, eth_hdr(skb)->h_source, ifindex))
++ 		goto drop;
++ 
++ 	skb_reset_network_header(skb);
++@@ -1898,7 +1908,7 @@ static void vxlan_encap_bypass(struct sk
++ 	}
++ 
++ 	if (dst_vxlan->flags & VXLAN_F_LEARN)
++-		vxlan_snoop(skb->dev, &loopback, eth_hdr(skb)->h_source);
+++		vxlan_snoop(skb->dev, &loopback, eth_hdr(skb)->h_source, 0);
++ 
++ 	u64_stats_update_begin(&tx_stats->syncp);
++ 	tx_stats->tx_packets++;
+diff --git a/target/linux/generic/patches-4.4/075-0004-vxlan-allow-multiple-VXLANs-with-same-VNI-for-IPv6-l.patch b/target/linux/generic/patches-4.4/075-0004-vxlan-allow-multiple-VXLANs-with-same-VNI-for-IPv6-l.patch
+new file mode 100644
+index 0000000000000000000000000000000000000000..c184c32385e6c802f1bed7647ce720f0e429f4a5
+--- /dev/null
++++ b/target/linux/generic/patches-4.4/075-0004-vxlan-allow-multiple-VXLANs-with-same-VNI-for-IPv6-l.patch
+@@ -0,0 +1,168 @@
++From 7a1fa05f8d460e2a81cb724f441f7346f950680a Mon Sep 17 00:00:00 2001
++Message-Id: <7a1fa05f8d460e2a81cb724f441f7346f950680a.1498005061.git.mschiffer@universe-factory.net>
++In-Reply-To: <434a1bb54b24b538f81d7945128b7ca25976d19b.1498005061.git.mschiffer@universe-factory.net>
++References: <434a1bb54b24b538f81d7945128b7ca25976d19b.1498005061.git.mschiffer@universe-factory.net>
++From: Matthias Schiffer <mschiffer@universe-factory.net>
++Date: Mon, 19 Jun 2017 10:04:00 +0200
++Subject: [PATCH 4/4] vxlan: allow multiple VXLANs with same VNI for IPv6
++ link-local addresses
++
++As link-local addresses are only valid for a single interface, we can allow
++to use the same VNI for multiple independent VXLANs, as long as the used
++interfaces are distinct. This way, VXLANs can always be used as a drop-in
++replacement for VLANs with greater ID space.
++
++This also extends VNI lookup to respect the ifindex when link-local IPv6
++addresses are used, so using the same VNI on multiple interfaces can
++actually work.
++
++Signed-off-by: Matthias Schiffer <mschiffer@universe-factory.net>
++Signed-off-by: David S. Miller <davem@davemloft.net>
++[Matthias Schiffer: rebase to v4.4.y]
++---
++ drivers/net/vxlan.c | 53 +++++++++++++++++++++++++++++++++++++----------------
++ 1 file changed, 37 insertions(+), 16 deletions(-)
++
++--- a/drivers/net/vxlan.c
+++++ b/drivers/net/vxlan.c
++@@ -242,22 +242,33 @@ static struct vxlan_sock *vxlan_find_soc
++ 	return NULL;
++ }
++ 
++-static struct vxlan_dev *vxlan_vs_find_vni(struct vxlan_sock *vs, u32 id)
+++static struct vxlan_dev *vxlan_vs_find_vni(struct vxlan_sock *vs, int ifindex,
+++					   u32 id)
++ {
++ 	struct vxlan_dev *vxlan;
++ 
++ 	hlist_for_each_entry_rcu(vxlan, vni_head(vs, id), hlist) {
++-		if (vxlan->default_dst.remote_vni == id)
++-			return vxlan;
+++		if (vxlan->default_dst.remote_vni != id)
+++			continue;
+++
+++		if (IS_ENABLED(CONFIG_IPV6)) {
+++			const struct vxlan_config *cfg = &vxlan->cfg;
+++
+++			if ((vxlan->flags & VXLAN_F_IPV6_LINKLOCAL) &&
+++			    cfg->remote_ifindex != ifindex)
+++				continue;
+++		}
+++
+++		return vxlan;
++ 	}
++ 
++ 	return NULL;
++ }
++ 
++ /* Look up VNI in a per net namespace table */
++-static struct vxlan_dev *vxlan_find_vni(struct net *net, u32 id,
++-					sa_family_t family, __be16 port,
++-					u32 flags)
+++static struct vxlan_dev *vxlan_find_vni(struct net *net, int ifindex,
+++				        u32 id, sa_family_t family,
+++					__be16 port, u32 flags)
++ {
++ 	struct vxlan_sock *vs;
++ 
++@@ -265,7 +276,7 @@ static struct vxlan_dev *vxlan_find_vni(
++ 	if (!vs)
++ 		return NULL;
++ 
++-	return vxlan_vs_find_vni(vs, id);
+++	return vxlan_vs_find_vni(vs, ifindex, id);
++ }
++ 
++ /* Fill in neighbour message in skbuff. */
++@@ -1174,7 +1185,7 @@ static void vxlan_rcv(struct vxlan_sock
++ 		vni = 0;
++ 
++ 	/* Is this VNI defined? */
++-	vxlan = vxlan_vs_find_vni(vs, vni);
+++	vxlan = vxlan_vs_find_vni(vs, skb->dev->ifindex, vni);
++ 	if (!vxlan)
++ 		goto drop;
++ 
++@@ -1942,6 +1953,7 @@ static void vxlan_xmit_one(struct sk_buf
++ 	u32 vni;
++ 	__be16 df = 0;
++ 	__u8 tos, ttl;
+++	int ifindex;
++ 	int err;
++ 	u32 flags = vxlan->flags;
++ 
++@@ -1950,6 +1962,7 @@ static void vxlan_xmit_one(struct sk_buf
++ 	if (rdst) {
++ 		dst_port = rdst->remote_port ? rdst->remote_port : vxlan->cfg.dst_port;
++ 		vni = rdst->remote_vni;
+++		ifindex = rdst->remote_ifindex;
++ 		dst = &rdst->remote_ip;
++ 	} else {
++ 		if (!info) {
++@@ -1959,6 +1972,7 @@ static void vxlan_xmit_one(struct sk_buf
++ 		}
++ 		dst_port = info->key.tp_dst ? : vxlan->cfg.dst_port;
++ 		vni = be64_to_cpu(info->key.tun_id);
+++		ifindex = 0;
++ 		remote_ip.sa.sa_family = ip_tunnel_info_af(info);
++ 		if (remote_ip.sa.sa_family == AF_INET)
++ 			remote_ip.sin.sin_addr.s_addr = info->key.u.ipv4.dst;
++@@ -2015,7 +2029,7 @@ static void vxlan_xmit_one(struct sk_buf
++ 		}
++ 
++ 		memset(&fl4, 0, sizeof(fl4));
++-		fl4.flowi4_oif = rdst ? rdst->remote_ifindex : 0;
+++		fl4.flowi4_oif = ifindex;
++ 		fl4.flowi4_tos = RT_TOS(tos);
++ 		fl4.flowi4_mark = skb->mark;
++ 		fl4.flowi4_proto = IPPROTO_UDP;
++@@ -2043,7 +2057,7 @@ static void vxlan_xmit_one(struct sk_buf
++ 			struct vxlan_dev *dst_vxlan;
++ 
++ 			ip_rt_put(rt);
++-			dst_vxlan = vxlan_find_vni(vxlan->net, vni,
+++			dst_vxlan = vxlan_find_vni(vxlan->net, ifindex, vni,
++ 						   dst->sa.sa_family, dst_port,
++ 						   vxlan->flags);
++ 			if (!dst_vxlan)
++@@ -2076,8 +2090,7 @@ static void vxlan_xmit_one(struct sk_buf
++ 			goto drop;
++ 		sk = vxlan->vn6_sock->sock->sk;
++ 
++-		ndst = vxlan6_get_route(vxlan, skb,
++-					rdst ? rdst->remote_ifindex : 0,
+++		ndst = vxlan6_get_route(vxlan, skb, ifindex,
++ 					&dst->sin6.sin6_addr, &saddr);
++ 		if (IS_ERR(ndst)) {
++ 			netdev_dbg(dev, "no route to %pI6\n",
++@@ -2101,7 +2114,7 @@ static void vxlan_xmit_one(struct sk_buf
++ 			struct vxlan_dev *dst_vxlan;
++ 
++ 			dst_release(ndst);
++-			dst_vxlan = vxlan_find_vni(vxlan->net, vni,
+++			dst_vxlan = vxlan_find_vni(vxlan->net, ifindex, vni,
++ 						   dst->sa.sa_family, dst_port,
++ 						   vxlan->flags);
++ 			if (!dst_vxlan)
++@@ -2889,10 +2902,18 @@ static int vxlan_dev_configure(struct ne
++ 		vxlan->cfg.age_interval = FDB_AGE_DEFAULT;
++ 
++ 	list_for_each_entry(tmp, &vn->vxlan_list, next) {
++-		if (tmp->cfg.vni == conf->vni &&
++-		    tmp->cfg.dst_port == vxlan->cfg.dst_port &&
++-		    (tmp->flags & (VXLAN_F_RCV_FLAGS | VXLAN_F_IPV6)) ==
+++		if (tmp->cfg.vni != conf->vni)
+++			continue;
+++		if (tmp->cfg.dst_port != vxlan->cfg.dst_port)
+++			continue;
+++		if ((tmp->flags & (VXLAN_F_RCV_FLAGS | VXLAN_F_IPV6)) !=
++ 		    (vxlan->flags & (VXLAN_F_RCV_FLAGS | VXLAN_F_IPV6)))
+++			continue;
+++
+++		if ((vxlan->flags & VXLAN_F_IPV6_LINKLOCAL) &&
+++		    tmp->cfg.remote_ifindex != vxlan->cfg.remote_ifindex)
+++			continue;
+++
++ 		return -EEXIST;
++ 	}
++