Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 26d31925 authored by Nicolas Dichtel's avatar Nicolas Dichtel Committed by David S. Miller
Browse files

tun: implement carrier change



The userspace may need to control the carrier state.

Signed-off-by: default avatarNicolas Dichtel <nicolas.dichtel@6wind.com>
Signed-off-by: default avatarDidier Pallard <didier.pallard@6wind.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent bf1c3ab8
Loading
Loading
Loading
Loading
+26 −1
Original line number Diff line number Diff line
@@ -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;
+1 −0
Original line number Diff line number Diff line
@@ -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