如何解决Linux无法使用ioctl删除持久性tun接口
如果在未设置TUNSETPERSIST的情况下创建了tun接口,则该接口将一直存在,直到关闭文件描述符为止。
so_q_nonpersistent.c
#include <assert.h>
#include <fcntl.h>
#include <linux/if.h>
#include <linux/if_tun.h>
#include <stdio.h>
#include <string.h>
#include <sys/ioctl.h>
#include <unistd.h>
#define D "tun0"
int main(){
assert(0==getuid());
struct ifreq ifc={.ifr_flags=IFF_TUN|IFF_NO_PI};
strncpy(ifc.ifr_name,D,IFNAMSIZ);
int tunfd=open("/dev/net/tun",O_RDWR);
assert(tunfd>=3);
assert(0==ioctl(tunfd,TUNSETIFF,&ifc));
// Interface appears
getchar();
close(tunfd);
tunfd=-1;
// Interface disappears
return 0;
}
如果设置了TUNSETPERSIST,它将在关闭的文件描述符中保留。
如何重新打开文件描述符并正确删除它?
so_q_persistent.c
#include <assert.h>
#include <errno.h>
#include <fcntl.h>
#include <linux/if.h>
#include <linux/if_tun.h>
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include <sys/ioctl.h>
#include <unistd.h>
#define D "tun0"
void tun_create(){
assert(0==getuid());
struct ifreq ifc={.ifr_flags=IFF_TUN|IFF_NO_PI};
strncpy(ifc.ifr_name,IFNAMSIZ);
int tunfd=open("/dev/net/tun",&ifc));
assert(0==ioctl(tunfd,TUNSETPERSIST,1));
close(tunfd);
tunfd=-1;
}
void tun_del(){
assert(0==getuid());
struct ifreq ifc={};
strncpy(ifc.ifr_name,O_RDWR);
assert(tunfd>=3);
errno=0;
const int r=ioctl(tunfd,0);
const int e=errno;
if(r!=0){
printf("%d %d %s\n",r,e,strerror(e));
assert(false);
}
close(tunfd);
tunfd=-1;
}
int main(){
tun_create();
tun_del();
return 0;
}
运行(无法删除)
$ sudo ./persist.out
-1 77 File descriptor in bad state
persist.out: so_q_persist.c:37: tun_del: Assertion `false' failed.
Aborted
An example without closing the file descriptor
if(delete) {
/* remove persistent status */
if(ioctl(tap_fd,0) < 0){
perror("disabling TUNSETPERSIST");
exit(1);
}
printf("Set '%s' nonpersistent\n",ifr.ifr_name);
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。