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 for Android: free password hash cracker in your pocket
[<prev] [next>] [day] [month] [year] [list]
Date:	Thu, 11 Apr 2013 19:16:34 +0900
From:	Atzm Watanabe <atzm@...atosphere.co.jp>
To:	netdev@...r.kernel.org
Cc:	"David S. Miller" <davem@...emloft.net>,
	Stephen Hemminger <stephen@...workplumber.org>,
	Cong Wang <xiyou.wangcong@...il.com>
Subject: [PATCH v2] vxlan: Allow setting destination to unicast address.

This patch allows setting VXLAN destination to unicast address.
It allows that VXLAN can be used as peer-to-peer tunnel without
multicast.

v2: use a new attribute REMOTE instead of GROUP based by
    Cong Wang's comments.

Signed-off-by: Atzm Watanabe <atzm@...atosphere.co.jp>
---
 drivers/net/vxlan.c          | 45 ++++++++++++++++++++++++++++++++++----------
 include/uapi/linux/if_link.h |  1 +
 2 files changed, 36 insertions(+), 10 deletions(-)

diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c
index 9a64715..ae589a3 100644
--- a/drivers/net/vxlan.c
+++ b/drivers/net/vxlan.c
@@ -106,7 +106,7 @@ struct vxlan_dev {
 	struct hlist_node hlist;
 	struct net_device *dev;
 	__u32		  vni;		/* virtual network id */
-	__be32	          gaddr;	/* multicast group */
+	__be32	          daddr;	/* destination address */
 	__be32		  saddr;	/* source address */
 	unsigned int      link;		/* link to multicast over */
 	__u16		  port_min;	/* source port range */
@@ -591,7 +591,7 @@ static bool vxlan_group_used(struct vxlan_net *vn,
 			if (!netif_running(vxlan->dev))
 				continue;
 
-			if (vxlan->gaddr == this->gaddr)
+			if (vxlan->daddr == this->daddr)
 				return true;
 		}
 
@@ -605,7 +605,7 @@ static int vxlan_join_group(struct net_device *dev)
 	struct vxlan_net *vn = net_generic(dev_net(dev), vxlan_net_id);
 	struct sock *sk = vn->sock->sk;
 	struct ip_mreqn mreq = {
-		.imr_multiaddr.s_addr	= vxlan->gaddr,
+		.imr_multiaddr.s_addr	= vxlan->daddr,
 		.imr_ifindex		= vxlan->link,
 	};
 	int err;
@@ -633,7 +633,7 @@ static int vxlan_leave_group(struct net_device *dev)
 	int err = 0;
 	struct sock *sk = vn->sock->sk;
 	struct ip_mreqn mreq = {
-		.imr_multiaddr.s_addr	= vxlan->gaddr,
+		.imr_multiaddr.s_addr	= vxlan->daddr,
 		.imr_ifindex		= vxlan->link,
 	};
 
@@ -1106,7 +1106,7 @@ static netdev_tx_t vxlan_xmit(struct sk_buff *skb, struct net_device *dev)
 		did_rsc = false;
 		group.remote_port = vxlan_port;
 		group.remote_vni = vxlan->vni;
-		group.remote_ip = vxlan->gaddr;
+		group.remote_ip = vxlan->daddr;
 		group.remote_ifindex = vxlan->link;
 		group.remote_next = 0;
 		rdst0 = &group;
@@ -1189,7 +1189,7 @@ static int vxlan_open(struct net_device *dev)
 	struct vxlan_dev *vxlan = netdev_priv(dev);
 	int err;
 
-	if (vxlan->gaddr) {
+	if (IN_MULTICAST(ntohl(vxlan->daddr))) {
 		err = vxlan_join_group(dev);
 		if (err)
 			return err;
@@ -1223,7 +1223,7 @@ static int vxlan_stop(struct net_device *dev)
 {
 	struct vxlan_dev *vxlan = netdev_priv(dev);
 
-	if (vxlan->gaddr)
+	if (IN_MULTICAST(ntohl(vxlan->daddr)))
 		vxlan_leave_group(dev);
 
 	del_timer_sync(&vxlan->age_timer);
@@ -1312,6 +1312,7 @@ static const struct nla_policy vxlan_policy[IFLA_VXLAN_MAX + 1] = {
 	[IFLA_VXLAN_GROUP]	= { .len = FIELD_SIZEOF(struct iphdr, daddr) },
 	[IFLA_VXLAN_LINK]	= { .type = NLA_U32 },
 	[IFLA_VXLAN_LOCAL]	= { .len = FIELD_SIZEOF(struct iphdr, saddr) },
+	[IFLA_VXLAN_REMOTE]	= { .len = FIELD_SIZEOF(struct iphdr, daddr) },
 	[IFLA_VXLAN_TOS]	= { .type = NLA_U8 },
 	[IFLA_VXLAN_TTL]	= { .type = NLA_U8 },
 	[IFLA_VXLAN_LEARNING]	= { .type = NLA_U8 },
@@ -1347,6 +1348,9 @@ static int vxlan_validate(struct nlattr *tb[], struct nlattr *data[])
 			return -ERANGE;
 	}
 
+	if (data[IFLA_VXLAN_GROUP] && data[IFLA_VXLAN_REMOTE])
+		return -EINVAL;
+
 	if (data[IFLA_VXLAN_GROUP]) {
 		__be32 gaddr = nla_get_be32(data[IFLA_VXLAN_GROUP]);
 		if (!IN_MULTICAST(ntohl(gaddr))) {
@@ -1355,6 +1359,14 @@ static int vxlan_validate(struct nlattr *tb[], struct nlattr *data[])
 		}
 	}
 
+	if (data[IFLA_VXLAN_REMOTE]) {
+		__be32 daddr = nla_get_be32(data[IFLA_VXLAN_REMOTE]);
+		if (IN_MULTICAST(ntohl(daddr))) {
+			pr_debug("remote address is not IPv4 unicast\n");
+			return -EADDRNOTAVAIL;
+		}
+	}
+
 	if (data[IFLA_VXLAN_PORT_RANGE]) {
 		const struct ifla_vxlan_port_range *p
 			= nla_data(data[IFLA_VXLAN_PORT_RANGE]);
@@ -1399,7 +1411,10 @@ static int vxlan_newlink(struct net *net, struct net_device *dev,
 	vxlan->vni = vni;
 
 	if (data[IFLA_VXLAN_GROUP])
-		vxlan->gaddr = nla_get_be32(data[IFLA_VXLAN_GROUP]);
+		vxlan->daddr = nla_get_be32(data[IFLA_VXLAN_GROUP]);
+
+	if (data[IFLA_VXLAN_REMOTE])
+		vxlan->daddr = nla_get_be32(data[IFLA_VXLAN_REMOTE]);
 
 	if (data[IFLA_VXLAN_LOCAL])
 		vxlan->saddr = nla_get_be32(data[IFLA_VXLAN_LOCAL]);
@@ -1483,6 +1498,7 @@ static size_t vxlan_get_size(const struct net_device *dev)
 		nla_total_size(sizeof(__be32)) +/* IFLA_VXLAN_GROUP */
 		nla_total_size(sizeof(__u32)) +	/* IFLA_VXLAN_LINK */
 		nla_total_size(sizeof(__be32))+	/* IFLA_VXLAN_LOCAL */
+		nla_total_size(sizeof(__be32))+	/* IFLA_VXLAN_REMOTE */
 		nla_total_size(sizeof(__u8)) +	/* IFLA_VXLAN_TTL */
 		nla_total_size(sizeof(__u8)) +	/* IFLA_VXLAN_TOS */
 		nla_total_size(sizeof(__u8)) +	/* IFLA_VXLAN_LEARNING */
@@ -1507,8 +1523,17 @@ static int vxlan_fill_info(struct sk_buff *skb, const struct net_device *dev)
 	if (nla_put_u32(skb, IFLA_VXLAN_ID, vxlan->vni))
 		goto nla_put_failure;
 
-	if (vxlan->gaddr && nla_put_be32(skb, IFLA_VXLAN_GROUP, vxlan->gaddr))
-		goto nla_put_failure;
+	if (vxlan->daddr) {
+		int err;
+
+		if (IN_MULTICAST(ntohl(vxlan->daddr)))
+			err = nla_put_be32(skb, IFLA_VXLAN_GROUP, vxlan->daddr);
+		else
+			err = nla_put_be32(skb, IFLA_VXLAN_REMOTE, vxlan->daddr);
+
+		if (err)
+			goto nla_put_failure;
+	}
 
 	if (vxlan->link && nla_put_u32(skb, IFLA_VXLAN_LINK, vxlan->link))
 		goto nla_put_failure;
diff --git a/include/uapi/linux/if_link.h b/include/uapi/linux/if_link.h
index 6b35c42..3b9dab9b 100644
--- a/include/uapi/linux/if_link.h
+++ b/include/uapi/linux/if_link.h
@@ -299,6 +299,7 @@ enum {
 	IFLA_VXLAN_GROUP,
 	IFLA_VXLAN_LINK,
 	IFLA_VXLAN_LOCAL,
+	IFLA_VXLAN_REMOTE,
 	IFLA_VXLAN_TTL,
 	IFLA_VXLAN_TOS,
 	IFLA_VXLAN_LEARNING,
-- 
1.8.1.5

--
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