Commit 0f22a3c6 authored by Matthias Schiffer's avatar Matthias Schiffer Committed by David S. Miller

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: default avatarMatthias Schiffer <mschiffer@universe-factory.net>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent ce44a4ae
...@@ -2907,11 +2907,35 @@ static int vxlan_config_validate(struct net *src_net, struct vxlan_config *conf, ...@@ -2907,11 +2907,35 @@ static int vxlan_config_validate(struct net *src_net, struct vxlan_config *conf,
if (conf->saddr.sa.sa_family != conf->remote_ip.sa.sa_family) if (conf->saddr.sa.sa_family != conf->remote_ip.sa.sa_family)
return -EINVAL; return -EINVAL;
if (vxlan_addr_multicast(&conf->saddr))
return -EINVAL;
if (conf->saddr.sa.sa_family == AF_INET6) { if (conf->saddr.sa.sa_family == AF_INET6) {
if (!IS_ENABLED(CONFIG_IPV6)) if (!IS_ENABLED(CONFIG_IPV6))
return -EPFNOSUPPORT; return -EPFNOSUPPORT;
use_ipv6 = true; use_ipv6 = true;
conf->flags |= VXLAN_F_IPV6; conf->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(&conf->remote_ip.sin6.sin6_addr);
if (local_type & IPV6_ADDR_LINKLOCAL) {
if (!(remote_type & IPV6_ADDR_LINKLOCAL) &&
(remote_type != IPV6_ADDR_ANY))
return -EINVAL;
conf->flags |= VXLAN_F_IPV6_LINKLOCAL;
} else {
if (remote_type ==
(IPV6_ADDR_UNICAST | IPV6_ADDR_LINKLOCAL))
return -EINVAL;
conf->flags &= ~VXLAN_F_IPV6_LINKLOCAL;
}
}
} }
if (conf->label && !use_ipv6) if (conf->label && !use_ipv6)
...@@ -2937,6 +2961,11 @@ static int vxlan_config_validate(struct net *src_net, struct vxlan_config *conf, ...@@ -2937,6 +2961,11 @@ static int vxlan_config_validate(struct net *src_net, struct vxlan_config *conf,
if (vxlan_addr_multicast(&conf->remote_ip)) if (vxlan_addr_multicast(&conf->remote_ip))
return -EINVAL; return -EINVAL;
#if IS_ENABLED(CONFIG_IPV6)
if (conf->flags & VXLAN_F_IPV6_LINKLOCAL)
return -EINVAL;
#endif
*lower = NULL; *lower = NULL;
} }
......
...@@ -258,6 +258,7 @@ struct vxlan_dev { ...@@ -258,6 +258,7 @@ struct vxlan_dev {
#define VXLAN_F_REMCSUM_NOPARTIAL 0x1000 #define VXLAN_F_REMCSUM_NOPARTIAL 0x1000
#define VXLAN_F_COLLECT_METADATA 0x2000 #define VXLAN_F_COLLECT_METADATA 0x2000
#define VXLAN_F_GPE 0x4000 #define VXLAN_F_GPE 0x4000
#define VXLAN_F_IPV6_LINKLOCAL 0x8000
/* Flags that are used in the receive path. These flags must match in /* Flags that are used in the receive path. These flags must match in
* order for a socket to be shareable * order for a socket to be shareable
...@@ -272,6 +273,7 @@ struct vxlan_dev { ...@@ -272,6 +273,7 @@ struct vxlan_dev {
/* Flags that can be set together with VXLAN_F_GPE. */ /* Flags that can be set together with VXLAN_F_GPE. */
#define VXLAN_F_ALLOWED_GPE (VXLAN_F_GPE | \ #define VXLAN_F_ALLOWED_GPE (VXLAN_F_GPE | \
VXLAN_F_IPV6 | \ VXLAN_F_IPV6 | \
VXLAN_F_IPV6_LINKLOCAL | \
VXLAN_F_UDP_ZERO_CSUM_TX | \ VXLAN_F_UDP_ZERO_CSUM_TX | \
VXLAN_F_UDP_ZERO_CSUM6_TX | \ VXLAN_F_UDP_ZERO_CSUM6_TX | \
VXLAN_F_UDP_ZERO_CSUM6_RX | \ VXLAN_F_UDP_ZERO_CSUM6_RX | \
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment