0028-generic-vxlan-backport-support-for-VXLAN-over-link-local-IPv6.patch 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436
  1. From: Matthias Schiffer <mschiffer@universe-factory.net>
  2. Date: Wed, 21 Jun 2017 00:54:57 +0200
  3. Subject: generic: vxlan: backport support for VXLAN over link-local IPv6
  4. 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
  5. new file mode 100644
  6. index 0000000000000000000000000000000000000000..439eb5d0f769f1cde23ff4deacc80728e82605f2
  7. --- /dev/null
  8. +++ b/target/linux/generic/patches-4.4/075-0001-vxlan-improve-validation-of-address-family-configura.patch
  9. @@ -0,0 +1,68 @@
  10. +From 434a1bb54b24b538f81d7945128b7ca25976d19b Mon Sep 17 00:00:00 2001
  11. +Message-Id: <434a1bb54b24b538f81d7945128b7ca25976d19b.1498005061.git.mschiffer@universe-factory.net>
  12. +From: Matthias Schiffer <mschiffer@universe-factory.net>
  13. +Date: Mon, 19 Jun 2017 10:03:57 +0200
  14. +Subject: [PATCH 1/4] vxlan: improve validation of address family configuration
  15. +
  16. +Address families of source and destination addresses must match, and
  17. +changelink operations can't change the address family.
  18. +
  19. +In addition, always use the VXLAN_F_IPV6 to check if a VXLAN device uses
  20. +IPv4 or IPv6.
  21. +
  22. +Signed-off-by: Matthias Schiffer <mschiffer@universe-factory.net>
  23. +Signed-off-by: David S. Miller <davem@davemloft.net>
  24. +[Matthias Schiffer: rebase to v4.4.y]
  25. +---
  26. + drivers/net/vxlan.c | 23 +++++++++++++++--------
  27. + 1 file changed, 15 insertions(+), 8 deletions(-)
  28. +
  29. +--- a/drivers/net/vxlan.c
  30. ++++ b/drivers/net/vxlan.c
  31. +@@ -2784,12 +2784,20 @@ static int vxlan_dev_configure(struct ne
  32. +
  33. + memcpy(&dst->remote_ip, &conf->remote_ip, sizeof(conf->remote_ip));
  34. +
  35. +- /* Unless IPv6 is explicitly requested, assume IPv4 */
  36. +- if (!dst->remote_ip.sa.sa_family)
  37. ++ if (!dst->remote_ip.sa.sa_family && !conf->saddr.sa.sa_family) {
  38. ++ /* Unless IPv6 is explicitly requested, assume IPv4 */
  39. + dst->remote_ip.sa.sa_family = AF_INET;
  40. ++ conf->saddr.sa.sa_family = AF_INET;
  41. ++ } else if (!dst->remote_ip.sa.sa_family) {
  42. ++ dst->remote_ip.sa.sa_family = conf->saddr.sa.sa_family;
  43. ++ } else if (!conf->saddr.sa.sa_family) {
  44. ++ conf->saddr.sa.sa_family = dst->remote_ip.sa.sa_family;
  45. ++ }
  46. ++
  47. ++ if (conf->saddr.sa.sa_family != dst->remote_ip.sa.sa_family)
  48. ++ return -EINVAL;
  49. +
  50. +- if (dst->remote_ip.sa.sa_family == AF_INET6 ||
  51. +- vxlan->cfg.saddr.sa.sa_family == AF_INET6) {
  52. ++ if (conf->saddr.sa.sa_family == AF_INET6) {
  53. + if (!IS_ENABLED(CONFIG_IPV6))
  54. + return -EPFNOSUPPORT;
  55. + use_ipv6 = true;
  56. +@@ -2843,11 +2851,9 @@ static int vxlan_dev_configure(struct ne
  57. +
  58. + list_for_each_entry(tmp, &vn->vxlan_list, next) {
  59. + if (tmp->cfg.vni == conf->vni &&
  60. +- (tmp->default_dst.remote_ip.sa.sa_family == AF_INET6 ||
  61. +- tmp->cfg.saddr.sa.sa_family == AF_INET6) == use_ipv6 &&
  62. + tmp->cfg.dst_port == vxlan->cfg.dst_port &&
  63. +- (tmp->flags & VXLAN_F_RCV_FLAGS) ==
  64. +- (vxlan->flags & VXLAN_F_RCV_FLAGS))
  65. ++ (tmp->flags & (VXLAN_F_RCV_FLAGS | VXLAN_F_IPV6)) ==
  66. ++ (vxlan->flags & (VXLAN_F_RCV_FLAGS | VXLAN_F_IPV6)))
  67. + return -EEXIST;
  68. + }
  69. +
  70. +@@ -2915,6 +2921,7 @@ static int vxlan_newlink(struct net *src
  71. +
  72. + if (data[IFLA_VXLAN_GROUP]) {
  73. + conf.remote_ip.sin.sin_addr.s_addr = nla_get_in_addr(data[IFLA_VXLAN_GROUP]);
  74. ++ conf.remote_ip.sa.sa_family = AF_INET;
  75. + } else if (data[IFLA_VXLAN_GROUP6]) {
  76. + if (!IS_ENABLED(CONFIG_IPV6))
  77. + return -EPFNOSUPPORT;
  78. 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
  79. new file mode 100644
  80. index 0000000000000000000000000000000000000000..abf9b8a0eae88aa5a64be5cc82a6827d4d562c55
  81. --- /dev/null
  82. +++ b/target/linux/generic/patches-4.4/075-0002-vxlan-check-valid-combinations-of-address-scopes.patch
  83. @@ -0,0 +1,84 @@
  84. +From 8956b9db43347a51e88dddc3c08fb88ff60dea54 Mon Sep 17 00:00:00 2001
  85. +Message-Id: <8956b9db43347a51e88dddc3c08fb88ff60dea54.1498005061.git.mschiffer@universe-factory.net>
  86. +In-Reply-To: <434a1bb54b24b538f81d7945128b7ca25976d19b.1498005061.git.mschiffer@universe-factory.net>
  87. +References: <434a1bb54b24b538f81d7945128b7ca25976d19b.1498005061.git.mschiffer@universe-factory.net>
  88. +From: Matthias Schiffer <mschiffer@universe-factory.net>
  89. +Date: Mon, 19 Jun 2017 10:03:58 +0200
  90. +Subject: [PATCH 2/4] vxlan: check valid combinations of address scopes
  91. +
  92. +* Multicast addresses are never valid as local address
  93. +* Link-local IPv6 unicast addresses may only be used as remote when the
  94. + local address is link-local as well
  95. +* Don't allow link-local IPv6 local/remote addresses without interface
  96. +
  97. +We also store in the flags field if link-local addresses are used for the
  98. +follow-up patches that actually make VXLAN over link-local IPv6 work.
  99. +
  100. +Signed-off-by: Matthias Schiffer <mschiffer@universe-factory.net>
  101. +Signed-off-by: David S. Miller <davem@davemloft.net>
  102. +[Matthias Schiffer: rebase to v4.4.y]
  103. +---
  104. + drivers/net/vxlan.c | 29 +++++++++++++++++++++++++++++
  105. + include/net/vxlan.h | 1 +
  106. + 2 files changed, 30 insertions(+)
  107. +
  108. +--- a/drivers/net/vxlan.c
  109. ++++ b/drivers/net/vxlan.c
  110. +@@ -2797,11 +2797,35 @@ static int vxlan_dev_configure(struct ne
  111. + if (conf->saddr.sa.sa_family != dst->remote_ip.sa.sa_family)
  112. + return -EINVAL;
  113. +
  114. ++ if (vxlan_addr_multicast(&conf->saddr))
  115. ++ return -EINVAL;
  116. ++
  117. + if (conf->saddr.sa.sa_family == AF_INET6) {
  118. + if (!IS_ENABLED(CONFIG_IPV6))
  119. + return -EPFNOSUPPORT;
  120. + use_ipv6 = true;
  121. + vxlan->flags |= VXLAN_F_IPV6;
  122. ++
  123. ++ if (!(conf->flags & VXLAN_F_COLLECT_METADATA)) {
  124. ++ int local_type =
  125. ++ ipv6_addr_type(&conf->saddr.sin6.sin6_addr);
  126. ++ int remote_type =
  127. ++ ipv6_addr_type(&dst->remote_ip.sin6.sin6_addr);
  128. ++
  129. ++ if (local_type & IPV6_ADDR_LINKLOCAL) {
  130. ++ if (!(remote_type & IPV6_ADDR_LINKLOCAL) &&
  131. ++ (remote_type != IPV6_ADDR_ANY))
  132. ++ return -EINVAL;
  133. ++
  134. ++ vxlan->flags |= VXLAN_F_IPV6_LINKLOCAL;
  135. ++ } else {
  136. ++ if (remote_type ==
  137. ++ (IPV6_ADDR_UNICAST | IPV6_ADDR_LINKLOCAL))
  138. ++ return -EINVAL;
  139. ++
  140. ++ vxlan->flags &= ~VXLAN_F_IPV6_LINKLOCAL;
  141. ++ }
  142. ++ }
  143. + }
  144. +
  145. + if (conf->remote_ifindex) {
  146. +@@ -2827,6 +2851,11 @@ static int vxlan_dev_configure(struct ne
  147. + dev->mtu = lowerdev->mtu - (use_ipv6 ? VXLAN6_HEADROOM : VXLAN_HEADROOM);
  148. +
  149. + needed_headroom = lowerdev->hard_header_len;
  150. ++ } else {
  151. ++#if IS_ENABLED(CONFIG_IPV6)
  152. ++ if (vxlan->flags & VXLAN_F_IPV6_LINKLOCAL)
  153. ++ return -EINVAL;
  154. ++#endif
  155. + }
  156. +
  157. + if (conf->mtu) {
  158. +--- a/include/net/vxlan.h
  159. ++++ b/include/net/vxlan.h
  160. +@@ -185,6 +185,7 @@ struct vxlan_dev {
  161. + #define VXLAN_F_GBP 0x800
  162. + #define VXLAN_F_REMCSUM_NOPARTIAL 0x1000
  163. + #define VXLAN_F_COLLECT_METADATA 0x2000
  164. ++#define VXLAN_F_IPV6_LINKLOCAL 0x8000
  165. +
  166. + /* Flags that are used in the receive path. These flags must match in
  167. + * order for a socket to be shareable
  168. 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
  169. new file mode 100644
  170. index 0000000000000000000000000000000000000000..5ebbce6e0682fff11b0d86c8df781a5c2fab5125
  171. --- /dev/null
  172. +++ b/target/linux/generic/patches-4.4/075-0003-vxlan-fix-snooping-for-link-local-IPv6-addresses.patch
  173. @@ -0,0 +1,88 @@
  174. +From e3bdb4bc6c4020e90c1bbafd91645ff3ae8966b9 Mon Sep 17 00:00:00 2001
  175. +Message-Id: <e3bdb4bc6c4020e90c1bbafd91645ff3ae8966b9.1498005061.git.mschiffer@universe-factory.net>
  176. +In-Reply-To: <434a1bb54b24b538f81d7945128b7ca25976d19b.1498005061.git.mschiffer@universe-factory.net>
  177. +References: <434a1bb54b24b538f81d7945128b7ca25976d19b.1498005061.git.mschiffer@universe-factory.net>
  178. +From: Matthias Schiffer <mschiffer@universe-factory.net>
  179. +Date: Mon, 19 Jun 2017 10:03:59 +0200
  180. +Subject: [PATCH 3/4] vxlan: fix snooping for link-local IPv6 addresses
  181. +
  182. +If VXLAN is run over link-local IPv6 addresses, it is necessary to store
  183. +the ifindex in the FDB entries. Otherwise, the used interface is undefined
  184. +and unicast communication will most likely fail.
  185. +
  186. +Support for link-local IPv4 addresses should be possible as well, but as
  187. +the semantics aren't as well defined as for IPv6, and there doesn't seem to
  188. +be much interest in having the support, it's not implemented for now.
  189. +
  190. +Signed-off-by: Matthias Schiffer <mschiffer@universe-factory.net>
  191. +Signed-off-by: David S. Miller <davem@davemloft.net>
  192. +[Matthias Schiffer: rebase to v4.4.y]
  193. +---
  194. + drivers/net/vxlan.c | 20 +++++++++++++++-----
  195. + 1 file changed, 15 insertions(+), 5 deletions(-)
  196. +
  197. +--- a/drivers/net/vxlan.c
  198. ++++ b/drivers/net/vxlan.c
  199. +@@ -947,16 +947,25 @@ out:
  200. + * Return true if packet is bogus and should be dropped.
  201. + */
  202. + static bool vxlan_snoop(struct net_device *dev,
  203. +- union vxlan_addr *src_ip, const u8 *src_mac)
  204. ++ union vxlan_addr *src_ip, const u8 *src_mac,
  205. ++ u32 src_ifindex)
  206. + {
  207. + struct vxlan_dev *vxlan = netdev_priv(dev);
  208. + struct vxlan_fdb *f;
  209. ++ u32 ifindex = 0;
  210. ++
  211. ++#if IS_ENABLED(CONFIG_IPV6)
  212. ++ if (src_ip->sa.sa_family == AF_INET6 &&
  213. ++ (ipv6_addr_type(&src_ip->sin6.sin6_addr) & IPV6_ADDR_LINKLOCAL))
  214. ++ ifindex = src_ifindex;
  215. ++#endif
  216. +
  217. + f = vxlan_find_mac(vxlan, src_mac);
  218. + if (likely(f)) {
  219. + struct vxlan_rdst *rdst = first_remote_rcu(f);
  220. +
  221. +- if (likely(vxlan_addr_equal(&rdst->remote_ip, src_ip)))
  222. ++ if (likely(vxlan_addr_equal(&rdst->remote_ip, src_ip) &&
  223. ++ rdst->remote_ifindex == ifindex))
  224. + return false;
  225. +
  226. + /* Don't migrate static entries, drop packets */
  227. +@@ -982,7 +991,7 @@ static bool vxlan_snoop(struct net_devic
  228. + NLM_F_EXCL|NLM_F_CREATE,
  229. + vxlan->cfg.dst_port,
  230. + vxlan->default_dst.remote_vni,
  231. +- 0, NTF_SELF);
  232. ++ ifindex, NTF_SELF);
  233. + spin_unlock(&vxlan->hash_lock);
  234. + }
  235. +
  236. +@@ -1157,6 +1166,7 @@ static void vxlan_rcv(struct vxlan_sock
  237. + struct vxlan_dev *vxlan;
  238. + struct pcpu_sw_netstats *stats;
  239. + union vxlan_addr saddr;
  240. ++ u32 ifindex = skb->dev->ifindex;
  241. + int err = 0;
  242. +
  243. + /* For flow based devices, map all packets to VNI 0 */
  244. +@@ -1196,7 +1206,7 @@ static void vxlan_rcv(struct vxlan_sock
  245. + }
  246. +
  247. + if ((vxlan->flags & VXLAN_F_LEARN) &&
  248. +- vxlan_snoop(skb->dev, &saddr, eth_hdr(skb)->h_source))
  249. ++ vxlan_snoop(skb->dev, &saddr, eth_hdr(skb)->h_source, ifindex))
  250. + goto drop;
  251. +
  252. + skb_reset_network_header(skb);
  253. +@@ -1898,7 +1908,7 @@ static void vxlan_encap_bypass(struct sk
  254. + }
  255. +
  256. + if (dst_vxlan->flags & VXLAN_F_LEARN)
  257. +- vxlan_snoop(skb->dev, &loopback, eth_hdr(skb)->h_source);
  258. ++ vxlan_snoop(skb->dev, &loopback, eth_hdr(skb)->h_source, 0);
  259. +
  260. + u64_stats_update_begin(&tx_stats->syncp);
  261. + tx_stats->tx_packets++;
  262. 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
  263. new file mode 100644
  264. index 0000000000000000000000000000000000000000..c184c32385e6c802f1bed7647ce720f0e429f4a5
  265. --- /dev/null
  266. +++ b/target/linux/generic/patches-4.4/075-0004-vxlan-allow-multiple-VXLANs-with-same-VNI-for-IPv6-l.patch
  267. @@ -0,0 +1,168 @@
  268. +From 7a1fa05f8d460e2a81cb724f441f7346f950680a Mon Sep 17 00:00:00 2001
  269. +Message-Id: <7a1fa05f8d460e2a81cb724f441f7346f950680a.1498005061.git.mschiffer@universe-factory.net>
  270. +In-Reply-To: <434a1bb54b24b538f81d7945128b7ca25976d19b.1498005061.git.mschiffer@universe-factory.net>
  271. +References: <434a1bb54b24b538f81d7945128b7ca25976d19b.1498005061.git.mschiffer@universe-factory.net>
  272. +From: Matthias Schiffer <mschiffer@universe-factory.net>
  273. +Date: Mon, 19 Jun 2017 10:04:00 +0200
  274. +Subject: [PATCH 4/4] vxlan: allow multiple VXLANs with same VNI for IPv6
  275. + link-local addresses
  276. +
  277. +As link-local addresses are only valid for a single interface, we can allow
  278. +to use the same VNI for multiple independent VXLANs, as long as the used
  279. +interfaces are distinct. This way, VXLANs can always be used as a drop-in
  280. +replacement for VLANs with greater ID space.
  281. +
  282. +This also extends VNI lookup to respect the ifindex when link-local IPv6
  283. +addresses are used, so using the same VNI on multiple interfaces can
  284. +actually work.
  285. +
  286. +Signed-off-by: Matthias Schiffer <mschiffer@universe-factory.net>
  287. +Signed-off-by: David S. Miller <davem@davemloft.net>
  288. +[Matthias Schiffer: rebase to v4.4.y]
  289. +---
  290. + drivers/net/vxlan.c | 53 +++++++++++++++++++++++++++++++++++++----------------
  291. + 1 file changed, 37 insertions(+), 16 deletions(-)
  292. +
  293. +--- a/drivers/net/vxlan.c
  294. ++++ b/drivers/net/vxlan.c
  295. +@@ -242,22 +242,33 @@ static struct vxlan_sock *vxlan_find_soc
  296. + return NULL;
  297. + }
  298. +
  299. +-static struct vxlan_dev *vxlan_vs_find_vni(struct vxlan_sock *vs, u32 id)
  300. ++static struct vxlan_dev *vxlan_vs_find_vni(struct vxlan_sock *vs, int ifindex,
  301. ++ u32 id)
  302. + {
  303. + struct vxlan_dev *vxlan;
  304. +
  305. + hlist_for_each_entry_rcu(vxlan, vni_head(vs, id), hlist) {
  306. +- if (vxlan->default_dst.remote_vni == id)
  307. +- return vxlan;
  308. ++ if (vxlan->default_dst.remote_vni != id)
  309. ++ continue;
  310. ++
  311. ++ if (IS_ENABLED(CONFIG_IPV6)) {
  312. ++ const struct vxlan_config *cfg = &vxlan->cfg;
  313. ++
  314. ++ if ((vxlan->flags & VXLAN_F_IPV6_LINKLOCAL) &&
  315. ++ cfg->remote_ifindex != ifindex)
  316. ++ continue;
  317. ++ }
  318. ++
  319. ++ return vxlan;
  320. + }
  321. +
  322. + return NULL;
  323. + }
  324. +
  325. + /* Look up VNI in a per net namespace table */
  326. +-static struct vxlan_dev *vxlan_find_vni(struct net *net, u32 id,
  327. +- sa_family_t family, __be16 port,
  328. +- u32 flags)
  329. ++static struct vxlan_dev *vxlan_find_vni(struct net *net, int ifindex,
  330. ++ u32 id, sa_family_t family,
  331. ++ __be16 port, u32 flags)
  332. + {
  333. + struct vxlan_sock *vs;
  334. +
  335. +@@ -265,7 +276,7 @@ static struct vxlan_dev *vxlan_find_vni(
  336. + if (!vs)
  337. + return NULL;
  338. +
  339. +- return vxlan_vs_find_vni(vs, id);
  340. ++ return vxlan_vs_find_vni(vs, ifindex, id);
  341. + }
  342. +
  343. + /* Fill in neighbour message in skbuff. */
  344. +@@ -1174,7 +1185,7 @@ static void vxlan_rcv(struct vxlan_sock
  345. + vni = 0;
  346. +
  347. + /* Is this VNI defined? */
  348. +- vxlan = vxlan_vs_find_vni(vs, vni);
  349. ++ vxlan = vxlan_vs_find_vni(vs, skb->dev->ifindex, vni);
  350. + if (!vxlan)
  351. + goto drop;
  352. +
  353. +@@ -1942,6 +1953,7 @@ static void vxlan_xmit_one(struct sk_buf
  354. + u32 vni;
  355. + __be16 df = 0;
  356. + __u8 tos, ttl;
  357. ++ int ifindex;
  358. + int err;
  359. + u32 flags = vxlan->flags;
  360. +
  361. +@@ -1950,6 +1962,7 @@ static void vxlan_xmit_one(struct sk_buf
  362. + if (rdst) {
  363. + dst_port = rdst->remote_port ? rdst->remote_port : vxlan->cfg.dst_port;
  364. + vni = rdst->remote_vni;
  365. ++ ifindex = rdst->remote_ifindex;
  366. + dst = &rdst->remote_ip;
  367. + } else {
  368. + if (!info) {
  369. +@@ -1959,6 +1972,7 @@ static void vxlan_xmit_one(struct sk_buf
  370. + }
  371. + dst_port = info->key.tp_dst ? : vxlan->cfg.dst_port;
  372. + vni = be64_to_cpu(info->key.tun_id);
  373. ++ ifindex = 0;
  374. + remote_ip.sa.sa_family = ip_tunnel_info_af(info);
  375. + if (remote_ip.sa.sa_family == AF_INET)
  376. + remote_ip.sin.sin_addr.s_addr = info->key.u.ipv4.dst;
  377. +@@ -2015,7 +2029,7 @@ static void vxlan_xmit_one(struct sk_buf
  378. + }
  379. +
  380. + memset(&fl4, 0, sizeof(fl4));
  381. +- fl4.flowi4_oif = rdst ? rdst->remote_ifindex : 0;
  382. ++ fl4.flowi4_oif = ifindex;
  383. + fl4.flowi4_tos = RT_TOS(tos);
  384. + fl4.flowi4_mark = skb->mark;
  385. + fl4.flowi4_proto = IPPROTO_UDP;
  386. +@@ -2043,7 +2057,7 @@ static void vxlan_xmit_one(struct sk_buf
  387. + struct vxlan_dev *dst_vxlan;
  388. +
  389. + ip_rt_put(rt);
  390. +- dst_vxlan = vxlan_find_vni(vxlan->net, vni,
  391. ++ dst_vxlan = vxlan_find_vni(vxlan->net, ifindex, vni,
  392. + dst->sa.sa_family, dst_port,
  393. + vxlan->flags);
  394. + if (!dst_vxlan)
  395. +@@ -2076,8 +2090,7 @@ static void vxlan_xmit_one(struct sk_buf
  396. + goto drop;
  397. + sk = vxlan->vn6_sock->sock->sk;
  398. +
  399. +- ndst = vxlan6_get_route(vxlan, skb,
  400. +- rdst ? rdst->remote_ifindex : 0,
  401. ++ ndst = vxlan6_get_route(vxlan, skb, ifindex,
  402. + &dst->sin6.sin6_addr, &saddr);
  403. + if (IS_ERR(ndst)) {
  404. + netdev_dbg(dev, "no route to %pI6\n",
  405. +@@ -2101,7 +2114,7 @@ static void vxlan_xmit_one(struct sk_buf
  406. + struct vxlan_dev *dst_vxlan;
  407. +
  408. + dst_release(ndst);
  409. +- dst_vxlan = vxlan_find_vni(vxlan->net, vni,
  410. ++ dst_vxlan = vxlan_find_vni(vxlan->net, ifindex, vni,
  411. + dst->sa.sa_family, dst_port,
  412. + vxlan->flags);
  413. + if (!dst_vxlan)
  414. +@@ -2889,10 +2902,18 @@ static int vxlan_dev_configure(struct ne
  415. + vxlan->cfg.age_interval = FDB_AGE_DEFAULT;
  416. +
  417. + list_for_each_entry(tmp, &vn->vxlan_list, next) {
  418. +- if (tmp->cfg.vni == conf->vni &&
  419. +- tmp->cfg.dst_port == vxlan->cfg.dst_port &&
  420. +- (tmp->flags & (VXLAN_F_RCV_FLAGS | VXLAN_F_IPV6)) ==
  421. ++ if (tmp->cfg.vni != conf->vni)
  422. ++ continue;
  423. ++ if (tmp->cfg.dst_port != vxlan->cfg.dst_port)
  424. ++ continue;
  425. ++ if ((tmp->flags & (VXLAN_F_RCV_FLAGS | VXLAN_F_IPV6)) !=
  426. + (vxlan->flags & (VXLAN_F_RCV_FLAGS | VXLAN_F_IPV6)))
  427. ++ continue;
  428. ++
  429. ++ if ((vxlan->flags & VXLAN_F_IPV6_LINKLOCAL) &&
  430. ++ tmp->cfg.remote_ifindex != vxlan->cfg.remote_ifindex)
  431. ++ continue;
  432. ++
  433. + return -EEXIST;
  434. + }
  435. +