diff mbox series

[net-next] tun: implement carrier change

Message ID 20181128181256.12526-1-nicolas.dichtel@6wind.com
State Accepted, archived
Delegated to: David Miller
Headers show
Series [net-next] tun: implement carrier change | expand

Commit Message

Nicolas Dichtel Nov. 28, 2018, 6:12 p.m. UTC
The userspace may need to control the carrier state.

Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com>
Signed-off-by: Didier Pallard <didier.pallard@6wind.com>
---
 drivers/net/tun.c           | 27 ++++++++++++++++++++++++++-
 include/uapi/linux/if_tun.h |  1 +
 2 files changed, 27 insertions(+), 1 deletion(-)

Comments

Andrew Lunn Nov. 28, 2018, 9:48 p.m. UTC | #1
On Wed, Nov 28, 2018 at 07:12:56PM +0100, Nicolas Dichtel wrote:
> The userspace may need to control the carrier state.

Hi Nicolas

Could you explain your user case a bit more.

Are you running a routing daemon on top of the interface, and want it
to reroute when the carrier goes down?

   Thanks
	Andrew
Nicolas Dichtel Nov. 29, 2018, 11:06 a.m. UTC | #2
Le 28/11/2018 à 22:48, Andrew Lunn a écrit :
> On Wed, Nov 28, 2018 at 07:12:56PM +0100, Nicolas Dichtel wrote:
>> The userspace may need to control the carrier state.
> 
> Hi Nicolas
Hi Andrew,

> 
> Could you explain your user case a bit more.
> 
> Are you running a routing daemon on top of the interface, and want it
> to reroute when the carrier goes down?
Sort of, we have a daemon that monitors the app and may re-route the traffic to
a secondary app if needed.


Regards,
Nicolas
Andrew Lunn Nov. 29, 2018, 4:36 p.m. UTC | #3
On Thu, Nov 29, 2018 at 12:06:18PM +0100, Nicolas Dichtel wrote:
> Le 28/11/2018 à 22:48, Andrew Lunn a écrit :
> > On Wed, Nov 28, 2018 at 07:12:56PM +0100, Nicolas Dichtel wrote:
> >> The userspace may need to control the carrier state.
> > 
> > Hi Nicolas
> Hi Andrew,
> 
> > 
> > Could you explain your user case a bit more.
> > 
> > Are you running a routing daemon on top of the interface, and want it
> > to reroute when the carrier goes down?
> Sort of, we have a daemon that monitors the app and may re-route the traffic to
> a secondary app if needed.

O.K, this sounds sensible.

It is often useful to explain the use case for changes like
this. People try to do crazy things sometimes.

Thanks
	Andrew
David Miller Dec. 1, 2018, 1:16 a.m. UTC | #4
From: Nicolas Dichtel <nicolas.dichtel@6wind.com>
Date: Wed, 28 Nov 2018 19:12:56 +0100

> The userspace may need to control the carrier state.
> 
> Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com>
> Signed-off-by: Didier Pallard <didier.pallard@6wind.com>

Applied.
diff mbox series

Patch

diff --git a/drivers/net/tun.c b/drivers/net/tun.c
index 56575f88d1fd..835c73f42ae7 100644
--- a/drivers/net/tun.c
+++ b/drivers/net/tun.c
@@ -1254,6 +1254,21 @@  static int tun_xdp(struct net_device *dev, struct netdev_bpf *xdp)
 	}
 }
 
+static int tun_net_change_carrier(struct net_device *dev, bool new_carrier)
+{
+	if (new_carrier) {
+		struct tun_struct *tun = netdev_priv(dev);
+
+		if (!tun->numqueues)
+			return -EPERM;
+
+		netif_carrier_on(dev);
+	} else {
+		netif_carrier_off(dev);
+	}
+	return 0;
+}
+
 static const struct net_device_ops tun_netdev_ops = {
 	.ndo_uninit		= tun_net_uninit,
 	.ndo_open		= tun_net_open,
@@ -1263,6 +1278,7 @@  static const struct net_device_ops tun_netdev_ops = {
 	.ndo_select_queue	= tun_select_queue,
 	.ndo_set_rx_headroom	= tun_set_headroom,
 	.ndo_get_stats64	= tun_net_get_stats64,
+	.ndo_change_carrier	= tun_net_change_carrier,
 };
 
 static void __tun_xdp_flush_tfile(struct tun_file *tfile)
@@ -1345,6 +1361,7 @@  static const struct net_device_ops tap_netdev_ops = {
 	.ndo_get_stats64	= tun_net_get_stats64,
 	.ndo_bpf		= tun_xdp,
 	.ndo_xdp_xmit		= tun_xdp_xmit,
+	.ndo_change_carrier	= tun_net_change_carrier,
 };
 
 static void tun_flow_init(struct tun_struct *tun)
@@ -3002,12 +3019,12 @@  static long __tun_chr_ioctl(struct file *file, unsigned int cmd,
 	struct net *net = sock_net(&tfile->sk);
 	struct tun_struct *tun;
 	void __user* argp = (void __user*)arg;
+	unsigned int ifindex, carrier;
 	struct ifreq ifr;
 	kuid_t owner;
 	kgid_t group;
 	int sndbuf;
 	int vnet_hdr_sz;
-	unsigned int ifindex;
 	int le;
 	int ret;
 	bool do_notify = false;
@@ -3291,6 +3308,14 @@  static long __tun_chr_ioctl(struct file *file, unsigned int cmd,
 		ret = tun_set_ebpf(tun, &tun->filter_prog, argp);
 		break;
 
+	case TUNSETCARRIER:
+		ret = -EFAULT;
+		if (copy_from_user(&carrier, argp, sizeof(carrier)))
+			goto unlock;
+
+		ret = tun_net_change_carrier(tun->dev, (bool)carrier);
+		break;
+
 	default:
 		ret = -EINVAL;
 		break;
diff --git a/include/uapi/linux/if_tun.h b/include/uapi/linux/if_tun.h
index ee432cd3018c..23a6753b37df 100644
--- a/include/uapi/linux/if_tun.h
+++ b/include/uapi/linux/if_tun.h
@@ -59,6 +59,7 @@ 
 #define TUNGETVNETBE _IOR('T', 223, int)
 #define TUNSETSTEERINGEBPF _IOR('T', 224, int)
 #define TUNSETFILTEREBPF _IOR('T', 225, int)
+#define TUNSETCARRIER _IOW('T', 226, int)
 
 /* TUNSETIFF ifr flags */
 #define IFF_TUN		0x0001