lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:	Wed, 17 Apr 2013 11:15:30 +0300
From:	Mike Rapoport <mike.rapoport@...ellosystems.com>
To:	Cong Wang <amwang@...hat.com>
Cc:	netdev@...r.kernel.org, David Stevens <dlstevens@...ibm.com>,
	Stephen Hemminger <stephen@...workplumber.org>,
	"David S. Miller" <davem@...emloft.net>
Subject: Re: [Patch net-next v4 3/5] vxlan: add ipv6 support

On Wed, Apr 17, 2013 at 01:10:20PM +0800, Cong Wang wrote:
> From: Cong Wang <amwang@...hat.com>
>
> This patch adds IPv6 support to vxlan device, as the new version
> RFC already mentioned it:
>
>    http://tools.ietf.org/html/draft-mahalingam-dutt-dcops-vxlan-03
>
> Cc: David Stevens <dlstevens@...ibm.com>
> Cc: Stephen Hemminger <stephen@...workplumber.org>
> Cc: David S. Miller <davem@...emloft.net>
> Signed-off-by: Cong Wang <amwang@...hat.com>
> ---
>  drivers/net/vxlan.c          |  639 +++++++++++++++++++++++++++++++++---------
>  include/uapi/linux/if_link.h |    2 +
>  2 files changed, 505 insertions(+), 136 deletions(-)
>
> diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c
> index f8ac900..43ed40f 100644
> --- a/drivers/net/vxlan.c
> +++ b/drivers/net/vxlan.c
> @@ -9,7 +9,6 @@
>   *
>   * TODO
>   *  - use IANA UDP port number (when defined)
> - *  - IPv6 (not in RFC)
>   */
>
>  #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
> @@ -42,6 +41,11 @@
>  #include <net/inet_ecn.h>
>  #include <net/net_namespace.h>
>  #include <net/netns/generic.h>
> +#if IS_ENABLED(CONFIG_IPV6)

It seems to me that some of the #ifdefs may be removed, especially on
the rtnetlink path.

> +#include <net/addrconf.h>
> +#include <net/ip6_route.h>
> +#include <net/ip6_tunnel.h>
> +#endif
>
>  #define VXLAN_VERSION	"0.1"
>

[ snip ]

> @@ -1342,6 +1603,25 @@ static int vxlan_validate(struct nlattr *tb[], struct nlattr *data[])
>  			return -ERANGE;
>  	}
>
> +	if (data[IFLA_VXLAN_REMOTE]) {
> +		__be32 gaddr = nla_get_be32(data[IFLA_VXLAN_REMOTE]);
> +		if (!IN_MULTICAST(ntohl(gaddr))) {
> +			pr_debug("group address is not IPv4 multicast\n");
> +			return -EADDRNOTAVAIL;
> +		}
> +	} else if (data[IFLA_VXLAN_REMOTE6]) {
> +#if IS_ENABLED(CONFIG_IPV6)
> +		struct in6_addr gaddr;
> +		nla_memcpy(&gaddr, data[IFLA_VXLAN_REMOTE6], sizeof(gaddr));
> +		if (!ipv6_addr_is_multicast(&gaddr)) {
> +			pr_debug("group address is not IPv6 multicast\n");
> +			return -EADDRNOTAVAIL;
> +		}
> +#else
> +		return -EPFNOSUPPORT;
> +#endif
> +	}

Adding back the test for multicast address contradicts the ability to
use unicast as default remote destination.

> +
>  	if (data[IFLA_VXLAN_PORT_RANGE]) {
>  		const struct ifla_vxlan_port_range *p
>  			= nla_data(data[IFLA_VXLAN_PORT_RANGE]);
> @@ -1386,11 +1666,31 @@ static int vxlan_newlink(struct net *net, struct net_device *dev,
>  	}
>  	dst->remote_vni = vni;
>
> -	if (data[IFLA_VXLAN_REMOTE])
> -		dst->remote_ip = nla_get_be32(data[IFLA_VXLAN_REMOTE]);
> +	if (data[IFLA_VXLAN_REMOTE]) {
> +		dst->remote_ip.va_sin = nla_get_be32(data[IFLA_VXLAN_REMOTE]);
> +		dst->remote_ip.va_sa = AF_INET;
> +	} else if (data[IFLA_VXLAN_REMOTE6]) {
> +#if IS_ENABLED(CONFIG_IPV6)
> +		nla_memcpy(&dst->remote_ip.va_sin6, data[IFLA_VXLAN_REMOTE6],
> +			   sizeof(struct in6_addr));
> +		dst->remote_ip.va_sa = AF_INET6;
> +#else
> +		return -EPFNOSUPPORT;
> +#endif
> +	}
>
> -	if (data[IFLA_VXLAN_LOCAL])
> -		vxlan->saddr = nla_get_be32(data[IFLA_VXLAN_LOCAL]);
> +	if (data[IFLA_VXLAN_LOCAL]) {
> +		vxlan->saddr.va_sin = nla_get_be32(data[IFLA_VXLAN_LOCAL]);
> +		vxlan->saddr.va_sa = AF_INET;
> +	} else if (data[IFLA_VXLAN_LOCAL6]) {
> +#if IS_ENABLED(CONFIG_IPV6)
> +		nla_memcpy(&vxlan->saddr.va_sin6, data[IFLA_VXLAN_LOCAL6],
> +			   sizeof(struct in6_addr));
> +		vxlan->saddr.va_sa = AF_INET6;
> +#else
> +		return -EPFNOSUPPORT;
> +#endif
> +	}
>
>  	if (data[IFLA_VXLAN_LINK] &&
>  	    (dst->remote_ifindex = nla_get_u32(data[IFLA_VXLAN_LINK]))) {
> @@ -1468,9 +1768,9 @@ static size_t vxlan_get_size(const struct net_device *dev)
>  {
>
>  	return nla_total_size(sizeof(__u32)) +	/* IFLA_VXLAN_ID */
> -		nla_total_size(sizeof(__be32)) +/* IFLA_VXLAN_REMOTE */
> +		nla_total_size(sizeof(struct in6_addr)) + /* IFLA_VXLAN_REMOTE{6} */
>  		nla_total_size(sizeof(__u32)) +	/* IFLA_VXLAN_LINK */
> -		nla_total_size(sizeof(__be32))+	/* IFLA_VXLAN_LOCAL */
> +		nla_total_size(sizeof(struct in6_addr)) + /* IFLA_VXLAN_LOCAL{6} */
>  		nla_total_size(sizeof(__u8)) +	/* IFLA_VXLAN_TTL */
>  		nla_total_size(sizeof(__u8)) +	/* IFLA_VXLAN_TOS */
>  		nla_total_size(sizeof(__u8)) +	/* IFLA_VXLAN_LEARNING */
> @@ -1496,14 +1796,34 @@ static int vxlan_fill_info(struct sk_buff *skb, const struct net_device *dev)
>  	if (nla_put_u32(skb, IFLA_VXLAN_ID, dst->remote_vni))
>  		goto nla_put_failure;
>
> -	if (dst->remote_ip && nla_put_be32(skb, IFLA_VXLAN_REMOTE, dst->remote_ip))
> -		goto nla_put_failure;
> +	if (!vxlan_addr_any(&dst->remote_ip)) {
> +		if (dst->remote_ip.va_sa == AF_INET) {
> +			if (nla_put_be32(skb, IFLA_VXLAN_REMOTE, dst->remote_ip.va_sin))
> +				goto nla_put_failure;
> +		} else {
> +#if IS_ENABLED(CONFIG_IPV6)
> +			if (nla_put(skb, IFLA_VXLAN_REMOTE6, sizeof(struct in6_addr),
> +				    &dst->remote_ip.va_sin6))
> +				goto nla_put_failure;
> +#endif
> +		}
> +	}
>
>  	if (dst->remote_ifindex && nla_put_u32(skb, IFLA_VXLAN_LINK, dst->remote_ifindex))
>  		goto nla_put_failure;
>
> -	if (vxlan->saddr && nla_put_be32(skb, IFLA_VXLAN_LOCAL, vxlan->saddr))
> -		goto nla_put_failure;
> +	if (!vxlan_addr_any(&vxlan->saddr)) {
> +		if (vxlan->saddr.va_sa == AF_INET) {
> +			if (nla_put_be32(skb, IFLA_VXLAN_LOCAL, vxlan->saddr.va_sin))
> +				goto nla_put_failure;
> +		} else {
> +#if IS_ENABLED(CONFIG_IPV6)
> +			if (nla_put(skb, IFLA_VXLAN_LOCAL6, sizeof(struct in6_addr),
> +				    &vxlan->saddr.va_sin6))
> +				goto nla_put_failure;
> +#endif
> +		}
> +	}
>
>  	if (nla_put_u8(skb, IFLA_VXLAN_TTL, vxlan->ttl) ||
>  	    nla_put_u8(skb, IFLA_VXLAN_TOS, vxlan->tos) ||
> @@ -1542,38 +1862,82 @@ static struct rtnl_link_ops vxlan_link_ops __read_mostly = {
>  	.fill_info	= vxlan_fill_info,
>  };
>
> -static __net_init int vxlan_init_net(struct net *net)
> +/* Create UDP socket for encapsulation receive. AF_INET6 socket
> + * could be used for both IPv4 and IPv6 communications.
> + */
> +#if IS_ENABLED(CONFIG_IPV6)
> +static __net_init int create_sock(struct net *net, struct sock **sk)
> +{
> +	struct vxlan_net *vn = net_generic(net, vxlan_net_id);
> +	struct sockaddr_in6 vxlan_addr = {
> +		.sin6_family = AF_INET6,
> +		.sin6_port = htons(vxlan_port),
> +	};
> +	int rc;
> +
> +	rc = sock_create_kern(AF_INET6, SOCK_DGRAM, IPPROTO_UDP, &vn->sock);
> +	if (rc < 0) {
> +		pr_debug("UDP socket create failed\n");
> +		return rc;
> +	}
> +	/* Put in proper namespace */
> +	*sk = vn->sock->sk;
> +	sk_change_net(*sk, net);
> +
> +	rc = kernel_bind(vn->sock, (struct sockaddr *)&vxlan_addr,
> +			 sizeof(struct sockaddr_in6));
> +	if (rc < 0) {
> +		pr_debug("bind for UDP socket %pI6:%u (%d)\n",
> +			 &vxlan_addr.sin6_addr, ntohs(vxlan_addr.sin6_port), rc);
> +		sk_release_kernel(*sk);
> +		vn->sock = NULL;
> +		return rc;
> +	}
> +	return 0;
> +}
> +#else
> +static __net_init int create_sock(struct net *net, struct sock **sk)
>  {
>  	struct vxlan_net *vn = net_generic(net, vxlan_net_id);
> -	struct sock *sk;
>  	struct sockaddr_in vxlan_addr = {
>  		.sin_family = AF_INET,
> +		.sin_port = htons(vxlan_port),
>  		.sin_addr.s_addr = htonl(INADDR_ANY),
>  	};
>  	int rc;
> -	unsigned h;
>
> -	/* Create UDP socket for encapsulation receive. */
>  	rc = sock_create_kern(AF_INET, SOCK_DGRAM, IPPROTO_UDP, &vn->sock);
>  	if (rc < 0) {
>  		pr_debug("UDP socket create failed\n");
>  		return rc;
>  	}
>  	/* Put in proper namespace */
> -	sk = vn->sock->sk;
> -	sk_change_net(sk, net);
> -
> -	vxlan_addr.sin_port = htons(vxlan_port);
> +	*sk = vn->sock->sk;
> +	sk_change_net(*sk, net);
>
> -	rc = kernel_bind(vn->sock, (struct sockaddr *) &vxlan_addr,
> -			 sizeof(vxlan_addr));
> +	rc = kernel_bind(vn->sock, (struct sockaddr *)&vxlan_addr,
> +			 sizeof(struct sockaddr_in));
>  	if (rc < 0) {
>  		pr_debug("bind for UDP socket %pI4:%u (%d)\n",
>  			 &vxlan_addr.sin_addr, ntohs(vxlan_addr.sin_port), rc);
> -		sk_release_kernel(sk);
> +		sk_release_kernel(*sk);
>  		vn->sock = NULL;
>  		return rc;
>  	}
> +	return 0;
> +}
> +#endif
> +
> +static __net_init int vxlan_init_net(struct net *net)
> +{
> +	struct vxlan_net *vn = net_generic(net, vxlan_net_id);
> +	struct sock *sk;
> +	int rc;
> +	unsigned h;
> +
> +	rc = create_sock(net, &sk);
> +	if (rc < 0)
> +		return rc;
>
>  	/* Disable multicast loopback */
>  	inet_sk(sk)->mc_loop = 0;
> @@ -1582,6 +1946,9 @@ static __net_init int vxlan_init_net(struct net *net)
>  	udp_sk(sk)->encap_type = 1;
>  	udp_sk(sk)->encap_rcv = vxlan_udp_encap_recv;
>  	udp_encap_enable();
> +#if IS_ENABLED(CONFIG_IPV6)
> +	udpv6_encap_enable();
> +#endif
>
>  	for (h = 0; h < VNI_HASH_SIZE; ++h)
>  		INIT_HLIST_HEAD(&vn->vni_list[h]);
> diff --git a/include/uapi/linux/if_link.h b/include/uapi/linux/if_link.h
> index 9922704..f47ab4c 100644
> --- a/include/uapi/linux/if_link.h
> +++ b/include/uapi/linux/if_link.h
> @@ -309,6 +309,8 @@ enum {
>  	IFLA_VXLAN_RSC,
>  	IFLA_VXLAN_L2MISS,
>  	IFLA_VXLAN_L3MISS,
> +	IFLA_VXLAN_REMOTE6,
> +	IFLA_VXLAN_LOCAL6,
>  	__IFLA_VXLAN_MAX
>  };
>  #define IFLA_VXLAN_MAX	(__IFLA_VXLAN_MAX - 1)
> --
> 1.7.7.6
>
> --
> To unsubscribe from this list: send the line "unsubscribe netdev" in
> the body of a message to majordomo@...r.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ