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