免费注册 查看新帖 |

Chinaunix

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

链路层直接指定MAC地址转发数据包问题? [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2012-03-27 10:41 |只看该作者 |倒序浏览
最近在做一个数据分流设备的模拟器,有一个功能如下:当收到指定IP地址对的数据包时(如:源IP 192.xx.xx.xx 目的 IP 10.xx.xx.xx),直接在链路层指定MAC地址将数据包发送出去。
我的方法是:在net/ethernet/eth.c的eth_type_trans()里面直接通过比较源IP与目地IP,然后修改源MAC地址与目的MAC地址,再将skb->data指向MAC头,最后通过dev_queue_xmit()将数据包发送到指定MAC地址的主机。
遇到问题:数据包的引用计数有问题skb->users,导致内核崩溃,我起初直接将通过atomic_set()将数据包的引用计数设置为0,在虚拟机上测试没问题,但是当我在真机上测试时,ping没问题,一开tcpdump抓包时,过一会儿就崩溃了。我估计是流量大了的问题,直接atomic_set()设置为0也应改不对。
求解:大家有什么好的方法吗,小弟,刚接触内核不久,还有很多东西不了接,能想到的方法也少。
代码实例:
if((strncmp(saddr,"192.168.1.10",3) == 0) && (strncmp(daddr,"10.10.0.10",2) == 0))
                             {
     
                                               memcpy(eth->h_source,rocky_tcp_G_net_fake_mac_addr,ETH_ALEN);
                                               eth->h_source[5] = rocky_tcp_G_net_fake_mac_addr[5] |0x01;
                                               memcpy(eth->h_dest,dmac_buf,ETH_ALEN);                                         
                                                skb_push(skb,ETH_HLEN);
                                               if(skb !=NULL)
                                               {
                                                      atomic_set(&skb->users,0);
                                                       //kfree_skb(skb);
                                                       dev_queue_xmit(skb);
                                                 }
                                               else
                                                        printk("@@@ skb is NULL!\n");
                                 }

论坛徽章:
6
金牛座
日期:2013-10-08 10:19:10技术图书徽章
日期:2013-10-14 16:24:09CU十二周年纪念徽章
日期:2013-10-24 15:41:34狮子座
日期:2013-11-24 19:26:19未羊
日期:2014-01-23 15:50:002015年亚洲杯之阿联酋
日期:2015-05-09 14:36:15
2 [报告]
发表于 2012-03-27 11:25 |只看该作者
回复 1# collition
    if(skb !=NULL)
                                               {
                                                      atomic_set(&skb->users,0);
                                                       //kfree_skb(skb);
                                                       dev_queue_xmit(skb);
                                                 }


可以尝试一下对数据包skb_copy后操作新的数据包,对老的数据包直接drop操作。

另外这个工作如果再IP层实现的话,扩展性应该更好一下。毕竟需要操作IP层是数据,建议把工作放在IP层来实现。

BTW:你的这个工作可以用章文嵩写的ipvs实现。

论坛徽章:
0
3 [报告]
发表于 2012-03-27 12:43 |只看该作者
atomic_set(&skb->users,0);

这种操作很危险。你怎么确定没有人在使用这个skb呢?
如果有地方引用的话,你发送后,skb被释放,然后别的地方一引用,自然挂了。

问个问题,你为什么要把users设置为0呢?

论坛徽章:
0
4 [报告]
发表于 2012-03-27 13:48 |只看该作者
回复 2# 瀚海书香


     这个模拟器的这项功能就是将数据包收上来,然后直接就转发出去,不需要多余的操作。对ip地址的操作可以用一个指针直接指向ip头将数据读出来就行。

论坛徽章:
0
5 [报告]
发表于 2012-03-27 13:56 |只看该作者
回复 3# GFree_Wind


    对,这样操作确实不对。但是不设置为0的话。在~/net/core/dev.c里面回引发net_tx_action()里面的一个bug
            net_tx_action()
                {
                         .......................
                           WARN_ON(atomic_read(&skb->users));
                         .......................
                }
                 但是在虚拟机内不会死机,真机上还没有试,应该回死掉。

论坛徽章:
0
6 [报告]
发表于 2012-03-27 14:07 |只看该作者
回复 2# 瀚海书香


    还有一点就是目地ip地址并不是这个分流设备,他只是一个中间设备。C(192.xx.xx.xx)->分流设备(192.xx.xx.xx;10.xx.xx.xx各一个)->S(10.xx.xx.xx)

论坛徽章:
0
7 [报告]
发表于 2012-03-27 14:15 |只看该作者
回复 5# collition

那你应该去找什么地方增加user引用,而不是强制将其设置为0.

   

论坛徽章:
6
金牛座
日期:2013-10-08 10:19:10技术图书徽章
日期:2013-10-14 16:24:09CU十二周年纪念徽章
日期:2013-10-24 15:41:34狮子座
日期:2013-11-24 19:26:19未羊
日期:2014-01-23 15:50:002015年亚洲杯之阿联酋
日期:2015-05-09 14:36:15
8 [报告]
发表于 2012-03-27 14:40 |只看该作者
回复 6# collition
还有一点就是目地ip地址并不是这个分流设备,他只是一个中间设备。C(192.xx.xx.xx)->分流设备(192.xx.xx.xx;10.xx.xx.xx各一个)->S(10.xx.xx.xx)


我知道你的意思,分流设备类似一个流量负载均衡的功能。ipvs的dr模式完全可以实现你的要求。

假设C为client,F为分流设备,S1,S2,S3为真实的服务器。

那么在F上配置一个IP0, VIP
S1上配置IP1, VIP
S2上配置IP2, VIP
S3上配置IP3, VIP

其中只有F上的VIP是进行arp应答的,S*上的VIP接口不进行arp应答。当C访问VIP的时候,会到达F,然后F进行direct route到S上。

论坛徽章:
0
9 [报告]
发表于 2012-03-27 14:59 |只看该作者
回复 8# 瀚海书香


1、对,这个我也遇到了。就是,当数据从另一个设备回来时,我在分流设备上打开转发功能,结果C/S直接就通信了。arp -n一看,缓存列表里面已经有对方的MAC地址了。基于是测试,我就把C的arp禁止掉(ifconfig eth0 -arp),然后添加一条到分流设备的arp -s xxxxxxx,分流设备同样添加一条arp -s xxxx到C。我觉得这样做不够灵活,应该彻底解决这个问题。我只知道echo 配置可以解决这个问题。
2、能给我说说是具体的那个*.c文件吗?("ipvs的dr模式完全可以实现你的要求。" 我想试试。
3、

论坛徽章:
6
金牛座
日期:2013-10-08 10:19:10技术图书徽章
日期:2013-10-14 16:24:09CU十二周年纪念徽章
日期:2013-10-24 15:41:34狮子座
日期:2013-11-24 19:26:19未羊
日期:2014-01-23 15:50:002015年亚洲杯之阿联酋
日期:2015-05-09 14:36:15
10 [报告]
发表于 2012-03-27 15:34 |只看该作者
回复 9# collition
ipvs的源码在 net/ipv4/ipvs/

   
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP