Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 12 Dec 2018 11:29:21 +0000 (UTC)
From:      Hans Petter Selasky <hselasky@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-11@freebsd.org
Subject:   svn commit: r341884 - stable/11/sys/net
Message-ID:  <201812121129.wBCBTLc1046427@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: hselasky
Date: Wed Dec 12 11:29:21 2018
New Revision: 341884
URL: https://svnweb.freebsd.org/changeset/base/341884

Log:
  MFC r339012:
  For changing the MTU on tun/tap devices, it should not matter whether it
  is done via using ifconfig, which uses a SIOCSIFMTU ioctl() command, or
  doing it using a TUNSIFINFO/TAPSIFINFO ioctl() command.
  Without this patch, for IPv6 the new MTU is not used when creating routes.
  Especially, when initiating TCP connections after increasing the MTU,
  the old MTU is still used to compute the MSS.
  Thanks to ae@ and bz@ for helping to improve the patch.
  
  Reviewed by:		ae@, bz@
  Sponsored by:		Netflix, Inc.
  Differential Revision:	https://reviews.freebsd.org/D17180

Modified:
  stable/11/sys/net/if.c
  stable/11/sys/net/if_tap.c
  stable/11/sys/net/if_tun.c
  stable/11/sys/net/if_var.h
Directory Properties:
  stable/11/   (props changed)

Modified: stable/11/sys/net/if.c
==============================================================================
--- stable/11/sys/net/if.c	Wed Dec 12 11:17:15 2018	(r341883)
+++ stable/11/sys/net/if.c	Wed Dec 12 11:29:21 2018	(r341884)
@@ -254,7 +254,6 @@ static int	if_setflag(struct ifnet *, int, int, int *,
 static int	if_transmit(struct ifnet *ifp, struct mbuf *m);
 static void	if_unroute(struct ifnet *, int flag, int fam);
 static void	link_rtrequest(int, struct rtentry *, struct rt_addrinfo *);
-static int	ifhwioctl(u_long, struct ifnet *, caddr_t, struct thread *);
 static int	if_delmulti_locked(struct ifnet *, struct ifmultiaddr *, int);
 static void	do_link_state_change(void *, int);
 static int	if_getgroup(struct ifgroupreq *, struct ifnet *);
@@ -2484,7 +2483,7 @@ ifr_data_get_ptr(void *ifrp)
 /*
  * Hardware specific interface ioctls.
  */
-static int
+int
 ifhwioctl(u_long cmd, struct ifnet *ifp, caddr_t data, struct thread *td)
 {
 	struct ifreq *ifr;

Modified: stable/11/sys/net/if_tap.c
==============================================================================
--- stable/11/sys/net/if_tap.c	Wed Dec 12 11:17:15 2018	(r341883)
+++ stable/11/sys/net/if_tap.c	Wed Dec 12 11:29:21 2018	(r341884)
@@ -723,10 +723,12 @@ tapifstart(struct ifnet *ifp)
 static int
 tapioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag, struct thread *td)
 {
+	struct ifreq		 ifr;
 	struct tap_softc	*tp = dev->si_drv1;
 	struct ifnet		*ifp = tp->tap_ifp;
 	struct tapinfo		*tapp = NULL;
 	int			 f;
+	int			 error;
 #if defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD5) || \
     defined(COMPAT_FREEBSD4)
 	int			 ival;
@@ -738,7 +740,18 @@ tapioctl(struct cdev *dev, u_long cmd, caddr_t data, i
 			if (ifp->if_type != tapp->type)
 				return (EPROTOTYPE);
 			mtx_lock(&tp->tap_mtx);
-			ifp->if_mtu = tapp->mtu;
+			if (ifp->if_mtu != tapp->mtu) {
+				strncpy(ifr.ifr_name, if_name(ifp), IFNAMSIZ);
+				ifr.ifr_mtu = tapp->mtu;
+				CURVNET_SET(ifp->if_vnet);
+				error = ifhwioctl(SIOCSIFMTU, ifp,
+				    (caddr_t)&ifr, td);
+				CURVNET_RESTORE();
+				if (error) {
+					mtx_unlock(&tp->tap_mtx);
+					return (error);
+				}
+			}
 			ifp->if_baudrate = tapp->baudrate;
 			mtx_unlock(&tp->tap_mtx);
 			break;

Modified: stable/11/sys/net/if_tun.c
==============================================================================
--- stable/11/sys/net/if_tun.c	Wed Dec 12 11:17:15 2018	(r341883)
+++ stable/11/sys/net/if_tun.c	Wed Dec 12 11:29:21 2018	(r341884)
@@ -662,24 +662,29 @@ static	int
 tunioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag,
     struct thread *td)
 {
-	int		error;
+	struct ifreq ifr;
 	struct tun_softc *tp = dev->si_drv1;
 	struct tuninfo *tunp;
+	int error;
 
 	switch (cmd) {
 	case TUNSIFINFO:
 		tunp = (struct tuninfo *)data;
-		if (tunp->mtu < IF_MINMTU)
-			return (EINVAL);
-		if (TUN2IFP(tp)->if_mtu != tunp->mtu) {
-			error = priv_check(td, PRIV_NET_SETIFMTU);
-			if (error)
-				return (error);
-		}
 		if (TUN2IFP(tp)->if_type != tunp->type)
 			return (EPROTOTYPE);
 		mtx_lock(&tp->tun_mtx);
-		TUN2IFP(tp)->if_mtu = tunp->mtu;
+		if (TUN2IFP(tp)->if_mtu != tunp->mtu) {
+			strncpy(ifr.ifr_name, if_name(TUN2IFP(tp)), IFNAMSIZ);
+			ifr.ifr_mtu = tunp->mtu;
+			CURVNET_SET(TUN2IFP(tp)->if_vnet);
+			error = ifhwioctl(SIOCSIFMTU, TUN2IFP(tp),
+			    (caddr_t)&ifr, td);
+			CURVNET_RESTORE();
+			if (error) {
+				mtx_unlock(&tp->tun_mtx);
+				return (error);
+			}
+		}
 		TUN2IFP(tp)->if_baudrate = tunp->baudrate;
 		mtx_unlock(&tp->tun_mtx);
 		break;

Modified: stable/11/sys/net/if_var.h
==============================================================================
--- stable/11/sys/net/if_var.h	Wed Dec 12 11:17:15 2018	(r341883)
+++ stable/11/sys/net/if_var.h	Wed Dec 12 11:29:21 2018	(r341884)
@@ -668,6 +668,8 @@ int if_hw_tsomax_update(if_t ifp, struct ifnet_hw_tsom
 /* accessors for struct ifreq */
 void *ifr_data_get_ptr(void *ifrp);
 
+int ifhwioctl(u_long, struct ifnet *, caddr_t, struct thread *);
+
 #ifdef DEVICE_POLLING
 enum poll_cmd { POLL_ONLY, POLL_AND_CHECK_STATUS };
 



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201812121129.wBCBTLc1046427>