免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 18703 | 回复: 14
打印 上一主题 下一主题

如何在linux程序中创建多个tun/tap虚拟网卡? [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2009-06-04 09:30 |只看该作者 |倒序浏览
我想在redhat enterprise 5的程序中创建多个tun/tap虚拟网卡。最初先创建一个tap设备,写了收包和发包函数,能正常工作,可是当创建两个tap设备时,出现了问题。我把创建的函数帖出来:
int tun_create(char *dev, int flags)
{
     struct ifreq ifr;
     int fd, err;
     assert(dev != NULL);
     if ((fd = open("/dev/net/tun", O_RDWR)) < 0)
         return fd;
     memset(&ifr, 0, sizeof(ifr));
     ifr.ifr_flags |= flags;
     if (*dev != '\0')
         strncpy(ifr.ifr_name, dev, IFNAMSIZ);     
     if ((err=ioctl(fd,TUNSETIFF,(void *)&ifr))<0){
   close(fd);
      return err;
  }
    // set_nonblock (fd);
     strcpy(dev,ifr.ifr_name);
     return fd;
}

int main(int argc, char *argv[])
{
        char tun_name[IFNAMSIZ]="tap0";
        char tun_name1[IFNAMSIZ]="tap1";   
        Tap=tun_create(tun_name, IFF_TAP | IFF_NO_PI);
        if (Tap< 0) {
                perror("tun_create");
                return 1;
                            }
        printf("TAP name is %s\n", tun_name);
        printf("Tap=%d\n",Tap);
        system("ifconfig tap0 10.0.0.185 netmask 255.255.0.0 up");
   
        Tap1=tun_create(tun_name1, IFF_TAP | IFF_NO_PI);
        if (Tap1< 0) {
                perror("tun_create");
                return 1;
                            }
        printf("TAP1 name is %s\n", tun_name1);
        printf("Tap1=%d\n",Tap1);
        system("ifconfig tap1 10.0.0.186 netmask 255.255.0.0 up");
}
这样就创建了tap0(IP地址:10.0.0.185)和tap1(IP地址:10.0.0.186)。但ping tap0时,发出ping 回应的却是tap1,感觉它们两个好像是一个设备。
请问应该怎样创建两个或多个tap设备?希望用过tun/tap虚拟网卡的高手帮忙,谢谢!
我的Email:simba226@163.com

论坛徽章:
0
2 [报告]
发表于 2009-06-04 10:01 |只看该作者
...........

[ 本帖最后由 fly6 于 2009-6-4 10:58 编辑 ]

论坛徽章:
0
3 [报告]
发表于 2009-06-04 15:57 |只看该作者
多谢2位的回复。
我试了modprobe tun
mknod /dev/net/tun0 c 10 200
mknod /dev/net/tun1 c 10 201
然后在程序里
int tun0_create(char *dev, int flags)
{
     struct ifreq ifr;
     int fd, err;
     assert(dev != NULL);
     if ((fd = open("/dev/net/tun0", O_RDWR)) < 0)
         return fd;
     memset(&ifr, 0, sizeof(ifr));
     ifr.ifr_flags |= flags;
     if (*dev != '\0')
         strncpy(ifr.ifr_name, dev, IFNAMSIZ);     
     if ((err=ioctl(fd,TUNSETIFF,(void *)&ifr))<0){
   close(fd);
      return err;
  }
   
     strcpy(dev,ifr.ifr_name);
     return fd;
}
int tun1_create(char *dev, int flags)
{
     struct ifreq ifr;
     int fd, err;
     assert(dev != NULL);
     if ((fd = open("/dev/net/tun1", O_RDWR)) < 0)
         return fd;
     memset(&ifr, 0, sizeof(ifr));
     ifr.ifr_flags |= flags;
     if (*dev != '\0')
         strncpy(ifr.ifr_name, dev, IFNAMSIZ);     
     if ((err=ioctl(fd,TUNSETIFF,(void *)&ifr))<0){
   close(fd);
      return err;
  }
   
     strcpy(dev,ifr.ifr_name);
     return fd;
}
int main(int argc, char *argv[])
{
        char tun_name[IFNAMSIZ]="tap0";
        char tun_name1[IFNAMSIZ]="tap1";   
        Tap=tun0_create(tun_name, IFF_TAP | IFF_NO_PI);
        if (Tap< 0) {
                perror("tun_create");
                return 1;
                            }
        printf("TAP name is %s\n", tun_name);
        printf("Tap=%d\n",Tap);
        system("ifconfig tap0 10.0.0.185 netmask 255.255.0.0 up");
   
        Tap1=tun1_create(tun_name1, IFF_TAP | IFF_NO_PI);
        if (Tap1< 0) {
                perror("tun_create");
                return 1;
                            }
        printf("TAP1 name is %s\n", tun_name1);
        printf("Tap1=%d\n",Tap1);
        system("ifconfig tap1 10.0.0.186 netmask 255.255.0.0 up");
}
可是运行时发现tun1_create函数里,fd = open("/dev/net/tun1", O_RDWR),fd返回-1,然后程序结束。请问怎么办?谢谢

论坛徽章:
0
4 [报告]
发表于 2009-06-04 18:59 |只看该作者
你确信你给的代码就是你测试用的代码?我用的环境是CentOS5.3,标准的发布内核(实际上是升级了又降回去了),测试并没有问题,是正常的:
[Cyberman@Cyberspace Network]$ ping -c 4 10.0.0.185
PING 10.0.0.185 (10.0.0.185) 56(84) bytes of data.
64 bytes from 10.0.0.185: icmp_seq=1 ttl=64 time=0.049 ms
64 bytes from 10.0.0.185: icmp_seq=2 ttl=64 time=0.049 ms
64 bytes from 10.0.0.185: icmp_seq=3 ttl=64 time=0.049 ms
64 bytes from 10.0.0.185: icmp_seq=4 ttl=64 time=0.048 ms

--- 10.0.0.185 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3000ms
rtt min/avg/max/mdev = 0.048/0.048/0.049/0.008 ms
[Cyberman@Cyberspace Network]$ ping -c 4 10.0.0.186
PING 10.0.0.186 (10.0.0.186) 56(84) bytes of data.
64 bytes from 10.0.0.186: icmp_seq=1 ttl=64 time=0.055 ms
64 bytes from 10.0.0.186: icmp_seq=2 ttl=64 time=0.050 ms
64 bytes from 10.0.0.186: icmp_seq=3 ttl=64 time=0.050 ms
64 bytes from 10.0.0.186: icmp_seq=4 ttl=64 time=0.052 ms

--- 10.0.0.186 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 2999ms
rtt min/avg/max/mdev = 0.050/0.051/0.055/0.009 ms
[Cyberman@Cyberspace Network]$



TUNSETIFF时输入结构的名称应该是没有意义的吧?反正内核中具体处理的代码还没看,测试出来是相同的。

[ 本帖最后由 Cyberman.Wu 于 2009-6-4 19:00 编辑 ]

tap_test.tar.bz2

927 Bytes, 下载次数: 56

论坛徽章:
0
5 [报告]
发表于 2009-06-05 08:11 |只看该作者

回复 #5 Cyberman.Wu 的帖子

谢谢回复!
你是在本机ping这两个虚拟网卡的吧?
我是从另外一个机子上的虚拟网卡来ping其中的一个虚拟网卡,而且它们都运行了olsr路由协议,结果发现ping某一个虚拟网卡时,回复的包却不一定来自它。而且一个ping 请求包它会回复多个相应包,相同的响应包后面加有(DUP!)。不知道怎么回事

论坛徽章:
0
6 [报告]
发表于 2009-06-05 09:57 |只看该作者

回复 #6 享耳亲斤 的帖子

我是从本机ping的。

不知道你的路由协议具体是怎么配置的,用的是哪个版本的内核?我在一块板子上测试时遇到过和你类似的问题,上面几个网口直接从二层收包,然后针对每个网口创建一个TAP,中间插错网口好像出现过类似的问题,当时用的内核版本是2.6.18.8,现在用的2.6.26.7好像不会出现同样的问题。

论坛徽章:
0
7 [报告]
发表于 2009-06-08 09:04 |只看该作者
高手帮帮忙,谢谢

论坛徽章:
0
8 [报告]
发表于 2009-06-09 10:31 |只看该作者

回复 #7 Cyberman.Wu 的帖子

我用的是redhat enterprise 5,内核是2.6.18。你也出现过类似的问题,比如ping主机上的tap0,回复ping的却是tap1这种情况吗?用2.6.26.7就没这样的问题吗?

论坛徽章:
0
9 [报告]
发表于 2009-06-11 11:41 |只看该作者
在两个主机上分别创建了两个tap虚拟网卡,每个虚拟网卡运行olsr路由协议,从其中一个ping另外一个虚拟网卡,得到如图所示结果:

论坛徽章:
0
10 [报告]
发表于 2009-06-11 18:47 |只看该作者
原帖由 享耳亲斤 于 2009-6-9 10:31 发表
我用的是redhat enterprise 5,内核是2.6.18。你也出现过类似的问题,比如ping主机上的tap0,回复ping的却是tap1这种情况吗?用2.6.26.7就没这样的问题吗?


现在我还不是很清楚是否和内核版本有关,那天测试时的结果比较奇怪,出现过类似的情况,不过后来没时间也就没再去测试;后来我在2.6.26.7版本上测试的确没再测出来。但那个现象好像也不是必然的,当时六个网口就我的本子现象比较奇怪。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP