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-next>] [day] [month] [year] [list]
Message-Id: <20180124035844.12932-1-isaac.lee@alliedtelesis.co.nz>
Date:   Wed, 24 Jan 2018 16:58:44 +1300
From:   Isaac Lee <isaac.lee@...iedtelesis.co.nz>
To:     netdev@...r.kernel.org
Cc:     Isaac Lee <isaac.lee@...iedtelesis.co.nz>
Subject: [PATCH] net:l2tp: Allow MAC to be configured via netlink

The linux kernel by default uses random MAC address
for l2tp interfaces. However, there are situations
where it is desirable to have a deterministic MAC address.

A sample scenario would be where the host IP stack is attached
directly to a tunnel hence the "random" address is now propagated
via ARP/ND to the other end of the tunnel. If the device reboots,
a new MAC is used and the communication over the tunnel will be
disrupted until the new MAC address is re-learned by the peer.
Therefore it can be useful to have the mac address the same across
reboots.

The patch makes the MAC address to be configurable via
netlink so that a userspace program can specify what MAC address to
use at interface creation time in the kernel.

Signed-off-by: Isaac Lee <isaac.lee@...iedtelesis.co.nz>
---
 include/uapi/linux/l2tp.h |  1 +
 net/l2tp/l2tp_core.h      |  1 +
 net/l2tp/l2tp_eth.c       |  5 ++++-
 net/l2tp/l2tp_netlink.c   | 10 ++++++++++
 4 files changed, 16 insertions(+), 1 deletion(-)

diff --git a/include/uapi/linux/l2tp.h b/include/uapi/linux/l2tp.h
index d84ce5c1c9aa..fec15fd774c4 100644
--- a/include/uapi/linux/l2tp.h
+++ b/include/uapi/linux/l2tp.h
@@ -126,6 +126,7 @@ enum {
 	L2TP_ATTR_IP6_DADDR,		/* struct in6_addr */
 	L2TP_ATTR_UDP_ZERO_CSUM6_TX,	/* flag */
 	L2TP_ATTR_UDP_ZERO_CSUM6_RX,	/* flag */
+	L2TP_ATTR_HWADDR,		/* 6 bytes */
 	L2TP_ATTR_PAD,
 	__L2TP_ATTR_MAX,
 };
diff --git a/net/l2tp/l2tp_core.h b/net/l2tp/l2tp_core.h
index 9534e16965cc..730021289ce5 100644
--- a/net/l2tp/l2tp_core.h
+++ b/net/l2tp/l2tp_core.h
@@ -71,6 +71,7 @@ struct l2tp_session_cfg {
 	int			mtu;
 	int			mru;
 	char			*ifname;
+	unsigned char		hwaddr[ETH_ALEN];
 };
 
 struct l2tp_session {
diff --git a/net/l2tp/l2tp_eth.c b/net/l2tp/l2tp_eth.c
index 5c366ecfa1cb..a07f50ca46ef 100644
--- a/net/l2tp/l2tp_eth.c
+++ b/net/l2tp/l2tp_eth.c
@@ -58,7 +58,9 @@ struct l2tp_eth_sess {
 
 static int l2tp_eth_dev_init(struct net_device *dev)
 {
-	eth_hw_addr_random(dev);
+	/* Use random MAC only when the interface is created without dev_addr */
+	if (!is_valid_ether_addr(dev->dev_addr))
+		eth_hw_addr_random(dev);
 	eth_broadcast_addr(dev->broadcast);
 	netdev_lockdep_set_classes(dev);
 
@@ -308,6 +310,7 @@ static int l2tp_eth_create(struct net *net, struct l2tp_tunnel *tunnel,
 	dev->min_mtu = 0;
 	dev->max_mtu = ETH_MAX_MTU;
 	l2tp_eth_adjust_mtu(tunnel, session, dev);
+	ether_addr_copy(dev->dev_addr, cfg->hwaddr);
 
 	priv = netdev_priv(dev);
 	priv->session = session;
diff --git a/net/l2tp/l2tp_netlink.c b/net/l2tp/l2tp_netlink.c
index a1f24fb2be98..a6740752bbde 100644
--- a/net/l2tp/l2tp_netlink.c
+++ b/net/l2tp/l2tp_netlink.c
@@ -25,6 +25,7 @@
 #include <linux/module.h>
 #include <linux/list.h>
 #include <net/net_namespace.h>
+#include <linux/etherdevice.h>
 
 #include <linux/l2tp.h>
 
@@ -607,6 +608,15 @@ static int l2tp_nl_cmd_session_create(struct sk_buff *skb, struct genl_info *inf
 	if (info->attrs[L2TP_ATTR_MRU])
 		cfg.mru = nla_get_u16(info->attrs[L2TP_ATTR_MRU]);
 
+	if (info->attrs[L2TP_ATTR_HWADDR]) {
+		unsigned char *hwaddr = nla_data(info->attrs[L2TP_ATTR_HWADDR]);
+		if (!is_valid_ether_addr(hwaddr)) {
+			ret = -EINVAL;
+			goto out_tunnel;
+		}
+		memcpy(&cfg.hwaddr, hwaddr, ETH_ALEN);
+	}
+
 #ifdef CONFIG_MODULES
 	if (l2tp_nl_cmd_ops[cfg.pw_type] == NULL) {
 		genl_unlock();
-- 
2.15.1

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ