@@ -1254,6 +1254,21 @@ static int tun_xdp(struct net_device *dev, struct netdev_bpf *xdp)
12541254 }
12551255}
12561256
1257+ static int tun_net_change_carrier (struct net_device * dev , bool new_carrier )
1258+ {
1259+ if (new_carrier ) {
1260+ struct tun_struct * tun = netdev_priv (dev );
1261+
1262+ if (!tun -> numqueues )
1263+ return - EPERM ;
1264+
1265+ netif_carrier_on (dev );
1266+ } else {
1267+ netif_carrier_off (dev );
1268+ }
1269+ return 0 ;
1270+ }
1271+
12571272static const struct net_device_ops tun_netdev_ops = {
12581273 .ndo_uninit = tun_net_uninit ,
12591274 .ndo_open = tun_net_open ,
@@ -1263,6 +1278,7 @@ static const struct net_device_ops tun_netdev_ops = {
12631278 .ndo_select_queue = tun_select_queue ,
12641279 .ndo_set_rx_headroom = tun_set_headroom ,
12651280 .ndo_get_stats64 = tun_net_get_stats64 ,
1281+ .ndo_change_carrier = tun_net_change_carrier ,
12661282};
12671283
12681284static void __tun_xdp_flush_tfile (struct tun_file * tfile )
@@ -1345,6 +1361,7 @@ static const struct net_device_ops tap_netdev_ops = {
13451361 .ndo_get_stats64 = tun_net_get_stats64 ,
13461362 .ndo_bpf = tun_xdp ,
13471363 .ndo_xdp_xmit = tun_xdp_xmit ,
1364+ .ndo_change_carrier = tun_net_change_carrier ,
13481365};
13491366
13501367static void tun_flow_init (struct tun_struct * tun )
@@ -3002,12 +3019,12 @@ static long __tun_chr_ioctl(struct file *file, unsigned int cmd,
30023019 struct net * net = sock_net (& tfile -> sk );
30033020 struct tun_struct * tun ;
30043021 void __user * argp = (void __user * )arg ;
3022+ unsigned int ifindex , carrier ;
30053023 struct ifreq ifr ;
30063024 kuid_t owner ;
30073025 kgid_t group ;
30083026 int sndbuf ;
30093027 int vnet_hdr_sz ;
3010- unsigned int ifindex ;
30113028 int le ;
30123029 int ret ;
30133030 bool do_notify = false;
@@ -3291,6 +3308,14 @@ static long __tun_chr_ioctl(struct file *file, unsigned int cmd,
32913308 ret = tun_set_ebpf (tun , & tun -> filter_prog , argp );
32923309 break ;
32933310
3311+ case TUNSETCARRIER :
3312+ ret = - EFAULT ;
3313+ if (copy_from_user (& carrier , argp , sizeof (carrier )))
3314+ goto unlock ;
3315+
3316+ ret = tun_net_change_carrier (tun -> dev , (bool )carrier );
3317+ break ;
3318+
32943319 default :
32953320 ret = - EINVAL ;
32963321 break ;
0 commit comments