Chinaunix首页 | 论坛 | 博客
  • 博客访问: 439777
  • 博文数量: 132
  • 博客积分: 2511
  • 博客等级: 大尉
  • 技术积分: 1385
  • 用 户 组: 普通用户
  • 注册时间: 2006-04-11 15:10
文章分类

全部博文(132)

文章存档

2012年(18)

2011年(35)

2010年(60)

2009年(19)

分类: LINUX

2011-02-25 22:51:24

前两天移植另一平台的ipv6功能到我们产品的平台,两个平台的主要区别就是,我们使用的这个平台带有交换芯片,在收包时要处理dsatag。
开始先验证当前内核及虚拟网卡驱动是否支持ipv6,使用了简单的ping6来验证,结果发现管理口(电口)上的ipv6请求能够被正确处理,但是虚拟网卡(使用的光口)上的icmpv6请求没有被正确处理(开始的邻居关系就没有建立起来,因为ping6的一端学不到我们机器的MAC),开始怀疑这个平台的发包有问题,查了半天;后来发现,从该平台向外发ping6包时,包能够发出去,而且对端有响应,只不过这个响应到达我们机器后,又没有被正确处理,因此基本可以确定是收包的流程出现了问题。
虚拟网卡部分的代码,基本没有修改,除了处理dsatag的部分,但在另一平台上是工作正常的。看代码看不出啥问题,只好一步步去跟了,最后发现在协议栈中丢弃该包时,是因为算icmpv6的option长度时出的问题,这时得到了一个非法值。这个值是由skb->tail减去另一指针得到的(应该是skb->transport_header再加一个偏移量),那应该就是这两个值中的某一值出了问题,后来经检查发现,skb->tail的值,从skb_alloc()之后就一直没有变过。原来在虚拟网卡的驱动代码中,用skb_alloc分配了一个skb结构后,在后面的代码中,手动设置了skb->len,但是没有设置skb->tail。后来改为用skb_put()来设置skb->len及skb->tail后,问题解决。
至于为什么另一平台的代码看上去工作正常,是因为在另一平台的处理过程中,只有当带有vlan的包才会去调用skb_alloc分配一个skb,然后将旧的skb中的内容去掉vlan封装后,再送至协议栈,但当没有vlan时,则不需要进行这种转换,因此直接skb_copy就可以。同事在测试时,没有测试带有vlan的情况,因此导致代码看上去工作正常。。
阅读(1789) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~