diff --git a/net/l2tp/l2tp_eth.c b/net/l2tp/l2tp_eth.c
index fd5ac2788e45..6fbb900bc3d1 100644
--- a/net/l2tp/l2tp_eth.c
+++ b/net/l2tp/l2tp_eth.c
@@ -103,28 +103,6 @@ static void l2tp_eth_get_stats64(struct net_device *dev,
 
 }
 
-static const struct net_device_ops l2tp_eth_netdev_ops = {
-	.ndo_init		= l2tp_eth_dev_init,
-	.ndo_uninit		= l2tp_eth_dev_uninit,
-	.ndo_start_xmit		= l2tp_eth_dev_xmit,
-	.ndo_get_stats64	= l2tp_eth_get_stats64,
-	.ndo_set_mac_address	= eth_mac_addr,
-};
-
-static struct device_type l2tpeth_type = {
-	.name = "l2tpeth",
-};
-
-static void l2tp_eth_dev_setup(struct net_device *dev)
-{
-	SET_NETDEV_DEVTYPE(dev, &l2tpeth_type);
-	ether_setup(dev);
-	dev->priv_flags		&= ~IFF_TX_SKB_SHARING;
-	dev->features		|= NETIF_F_LLTX;
-	dev->netdev_ops		= &l2tp_eth_netdev_ops;
-	dev->needs_free_netdev	= true;
-}
-
 static void l2tp_eth_dev_recv(struct l2tp_session *session, struct sk_buff *skb, int data_len)
 {
 	struct l2tp_eth_sess *spriv = l2tp_session_priv(session);
@@ -215,44 +193,73 @@ static void l2tp_eth_show(struct seq_file *m, void *arg)
 	dev_put(dev);
 }
 
-static void l2tp_eth_adjust_mtu(struct l2tp_tunnel *tunnel,
-				struct l2tp_session *session,
-				struct net_device *dev)
+static unsigned int l2tp_eth_best_mtu(struct net_device *dev)
 {
-	unsigned int overhead = 0;
-	u32 l3_overhead = 0;
-	u32 mtu;
+	struct l2tp_eth *priv = netdev_priv(dev);
+	struct l2tp_session *session = priv->session;
+	struct l2tp_tunnel *tunnel = session->tunnel;
+	unsigned int mtu, overhead = 0;
 
-	/* if the encap is UDP, account for UDP header size */
-	if (tunnel->encap == L2TP_ENCAPTYPE_UDP) {
-		overhead += sizeof(struct udphdr);
-		dev->needed_headroom += sizeof(struct udphdr);
+	if (tunnel->sock) {
+		lock_sock(tunnel->sock);
+		overhead = kernel_sock_ip_overhead(tunnel->sock);
+		release_sock(tunnel->sock);
 	}
 
-	lock_sock(tunnel->sock);
-	l3_overhead = kernel_sock_ip_overhead(tunnel->sock);
-	release_sock(tunnel->sock);
-
-	if (l3_overhead == 0) {
+	if (overhead == 0) {
 		/* L3 Overhead couldn't be identified, this could be
 		 * because tunnel->sock was NULL or the socket's
 		 * address family was not IPv4 or IPv6,
-		 * dev mtu stays at 1500.
+		 * assume existing MTU is best
 		 */
-		return;
+		return dev->mtu;
 	}
-	/* Adjust MTU, factor overhead - underlay L3, overlay L2 hdr
-	 * UDP overhead, if any, was already factored in above.
-	 */
-	overhead += session->hdr_len + ETH_HLEN + l3_overhead;
 
+	/* if the encap is UDP, account for UDP header size */
+	if (tunnel->encap == L2TP_ENCAPTYPE_UDP)
+		overhead += sizeof(struct udphdr);
+
+	/* Maximize MTU, factor in overhead - overlay L2 and Geneve header.
+	 * UDP overhead, if any, and underlay L3 already factored in above.
+	 */
+	overhead += session->hdr_len + ETH_HLEN;
 	mtu = l2tp_tunnel_dst_mtu(tunnel) - overhead;
 	if (mtu < dev->min_mtu || mtu > dev->max_mtu)
-		dev->mtu = ETH_DATA_LEN - overhead;
-	else
-		dev->mtu = mtu;
+		mtu = ETH_DATA_LEN - overhead;
 
-	dev->needed_headroom += session->hdr_len;
+	return mtu;
+}
+
+static int l2tp_eth_change_mtu(struct net_device *dev, int new_mtu)
+{
+	unsigned int best_mtu = l2tp_eth_best_mtu(dev);
+
+	dev->mtu = new_mtu;
+	__vlan_constrain_mtu(dev, best_mtu);
+	return 0;
+}
+
+static const struct net_device_ops l2tp_eth_netdev_ops = {
+	.ndo_init		= l2tp_eth_dev_init,
+	.ndo_uninit		= l2tp_eth_dev_uninit,
+	.ndo_start_xmit		= l2tp_eth_dev_xmit,
+	.ndo_get_stats64	= l2tp_eth_get_stats64,
+	.ndo_set_mac_address	= eth_mac_addr,
+	.ndo_change_mtu		= l2tp_eth_change_mtu,
+};
+
+static struct device_type l2tpeth_type = {
+	.name = "l2tpeth",
+};
+
+static void l2tp_eth_dev_setup(struct net_device *dev)
+{
+	SET_NETDEV_DEVTYPE(dev, &l2tpeth_type);
+	ether_setup(dev);
+	dev->priv_flags		&= ~IFF_TX_SKB_SHARING;
+	dev->features		|= NETIF_F_LLTX;
+	dev->netdev_ops		= &l2tp_eth_netdev_ops;
+	dev->needs_free_netdev	= true;
 }
 
 static int l2tp_eth_create(struct net *net, struct l2tp_tunnel *tunnel,
@@ -289,14 +296,19 @@ static int l2tp_eth_create(struct net *net, struct l2tp_tunnel *tunnel,
 		goto err_sess;
 	}
 
-	dev_net_set(dev, net);
-	dev->min_mtu = 0;
-	dev->max_mtu = ETH_MAX_MTU;
-	l2tp_eth_adjust_mtu(tunnel, session, dev);
+	if (tunnel->encap == L2TP_ENCAPTYPE_UDP)
+		dev->needed_headroom += sizeof(struct udphdr);
+	dev->needed_headroom += session->hdr_len;
 
 	priv = netdev_priv(dev);
 	priv->session = session;
 
+	dev_net_set(dev, net);
+	dev->min_mtu = 0;
+	dev->max_mtu = ETH_MAX_MTU;
+	dev->mtu = l2tp_eth_best_mtu(dev);
+	dev->priv_flags |= IFF_NO_VLAN_ROOM;
+
 	session->recv_skb = l2tp_eth_dev_recv;
 	session->session_close = l2tp_eth_delete;
 	if (IS_ENABLED(CONFIG_L2TP_DEBUGFS))
