免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
123
最近访问板块 发新帖
楼主: fengfengdiandia
打印 上一主题 下一主题

[内核模块] netfilter模块修改forward报文 [复制链接]

论坛徽章:
20
程序设计版块每日发帖之星
日期:2015-08-17 06:20:00程序设计版块每日发帖之星
日期:2016-07-16 06:20:00程序设计版块每日发帖之星
日期:2016-07-18 06:20:00每日论坛发贴之星
日期:2016-07-18 06:20:00黑曼巴
日期:2016-12-26 16:00:3215-16赛季CBA联赛之江苏
日期:2017-06-26 11:05:5615-16赛季CBA联赛之上海
日期:2017-07-21 18:12:5015-16赛季CBA联赛之青岛
日期:2017-09-04 17:32:0515-16赛季CBA联赛之吉林
日期:2018-03-26 10:02:16程序设计版块每日发帖之星
日期:2016-07-15 06:20:0015-16赛季CBA联赛之江苏
日期:2016-07-07 18:37:512015亚冠之萨济拖拉机
日期:2015-08-17 12:21:08
21 [报告]
发表于 2015-07-13 12:13 |只看该作者
"更改了校验和的方式"具体指什么?方便的话罗列一下校验和相关的操作步骤(以及两种方式下的差异)。

如果都是软件校验,理论上没有什么区别的。

从结果上看,应该跟硬件Offload Checksum有关系。相关字读 skb->csum, skb->ip_summed。

Rx: skb->ip_summed
* CHECKSUM_NONE: 网卡不支持校验(或其它原因),需要软件校验;
* CHECKSUM_UNNECESSARY:网卡已经验证4层伪头,软件无需验证;
* CHECKSUM_HW: 网卡校验和,结果存在skb->csum,软件需要做额外校验调整。(例如UDP的IP分片,暂时无法得到udp伪头)

Tx: skb->ip_summed:
* NONE: 协议栈已经计算了cheksum,网卡无需参与;
* HW: 由网卡计算校验,校验和填在skb->h.raw+skb->csum(即csum代表一个偏移,用来存储最后的校验和);
* UNNECSSARY: 未用=NONE

Rx和Tx的含义不太一样,对于forward报文,如果发生了内容调整,最稳妥的办法是重新计算(例如nat、nat_ftp等)。

论坛徽章:
2
2015年亚洲杯之日本
日期:2015-03-25 11:21:322015亚冠之柏太阳神
日期:2015-07-13 10:36:04
22 [报告]
发表于 2015-07-15 12:44 |只看该作者
回复 21# nswcfd

forward 的处理较 local_in 的要少一些
区别如下:
1. seq 和 ack
local_in: 在报文长度增加后,手动维护后面所有的 seq 和 ack
forward:在报文长度增加后,去掉了 seq 和 ack 的处理部分

2. skb->csum 和 ip_summed
local_in: skb->csum = csum_partial(tcph, tcp_len, 0);
              ip_summed = CHECKSUM_NONE;
forward:重新计算 IP 和 TCP checksum 时,没有去填写 skb->csum 和 ip_summed 的值


就这些地方不同,其余部分和原来没有什么出入,感觉很奇怪,尤其是没有去维护 seq 和 ack number 这部分,到现在也没想明白。

   

论坛徽章:
20
程序设计版块每日发帖之星
日期:2015-08-17 06:20:00程序设计版块每日发帖之星
日期:2016-07-16 06:20:00程序设计版块每日发帖之星
日期:2016-07-18 06:20:00每日论坛发贴之星
日期:2016-07-18 06:20:00黑曼巴
日期:2016-12-26 16:00:3215-16赛季CBA联赛之江苏
日期:2017-06-26 11:05:5615-16赛季CBA联赛之上海
日期:2017-07-21 18:12:5015-16赛季CBA联赛之青岛
日期:2017-09-04 17:32:0515-16赛季CBA联赛之吉林
日期:2018-03-26 10:02:16程序设计版块每日发帖之星
日期:2016-07-15 06:20:0015-16赛季CBA联赛之江苏
日期:2016-07-07 18:37:512015亚冠之萨济拖拉机
日期:2015-08-17 12:21:08
23 [报告]
发表于 2015-07-15 19:55 |只看该作者
forward不去修改后续报文的seq/ack,还能正常工作?? 是很奇怪

论坛徽章:
20
程序设计版块每日发帖之星
日期:2015-08-17 06:20:00程序设计版块每日发帖之星
日期:2016-07-16 06:20:00程序设计版块每日发帖之星
日期:2016-07-18 06:20:00每日论坛发贴之星
日期:2016-07-18 06:20:00黑曼巴
日期:2016-12-26 16:00:3215-16赛季CBA联赛之江苏
日期:2017-06-26 11:05:5615-16赛季CBA联赛之上海
日期:2017-07-21 18:12:5015-16赛季CBA联赛之青岛
日期:2017-09-04 17:32:0515-16赛季CBA联赛之吉林
日期:2018-03-26 10:02:16程序设计版块每日发帖之星
日期:2016-07-15 06:20:0015-16赛季CBA联赛之江苏
日期:2016-07-07 18:37:512015亚冠之萨济拖拉机
日期:2015-08-17 12:21:08
24 [报告]
发表于 2015-07-15 19:56 |只看该作者
这里的forward对应的是可以正常转发的情况? (换句话说,不正常的转发使用的代码跟local_in是一样的?)

论坛徽章:
20
程序设计版块每日发帖之星
日期:2015-08-17 06:20:00程序设计版块每日发帖之星
日期:2016-07-16 06:20:00程序设计版块每日发帖之星
日期:2016-07-18 06:20:00每日论坛发贴之星
日期:2016-07-18 06:20:00黑曼巴
日期:2016-12-26 16:00:3215-16赛季CBA联赛之江苏
日期:2017-06-26 11:05:5615-16赛季CBA联赛之上海
日期:2017-07-21 18:12:5015-16赛季CBA联赛之青岛
日期:2017-09-04 17:32:0515-16赛季CBA联赛之吉林
日期:2018-03-26 10:02:16程序设计版块每日发帖之星
日期:2016-07-15 06:20:0015-16赛季CBA联赛之江苏
日期:2016-07-07 18:37:512015亚冠之萨济拖拉机
日期:2015-08-17 12:21:08
25 [报告]
发表于 2015-07-15 19:58 |只看该作者
能否确认一下,forward下对应的skb->csum和skb->ip_summed的值分别是多少?(跟local_in的原始值有没有不同?)

论坛徽章:
2
2015年亚洲杯之日本
日期:2015-03-25 11:21:322015亚冠之柏太阳神
日期:2015-07-13 10:36:04
26 [报告]
发表于 2015-07-15 20:06 |只看该作者
回复 24# nswcfd

嗯,用 local_in 的那一组校验方式等,在 forward 这不太行得通,不知道是不是只有我的才这样?

对了,我的内核是 Linux 2.6.32-131.0.15.el6.x86_64
   

论坛徽章:
2
2015年亚洲杯之日本
日期:2015-03-25 11:21:322015亚冠之柏太阳神
日期:2015-07-13 10:36:04
27 [报告]
发表于 2015-07-15 20:07 |只看该作者
回复 25# nswcfd

好,等我明天打印出来看看
   

论坛徽章:
2
2015年亚洲杯之日本
日期:2015-03-25 11:21:322015亚冠之柏太阳神
日期:2015-07-13 10:36:04
28 [报告]
发表于 2015-07-16 10:30 |只看该作者
nswcfd 发表于 2015-07-15 19:58
能否确认一下,forward下对应的skb->csum和skb->ip_summed的值分别是多少?(跟local_in的原始值有没有不同 ...


forward 的 skb->csum 和 local_in 的不同,skb->ip_summed 的值是 CHECKSUM_UNNECESSARY

论坛徽章:
20
程序设计版块每日发帖之星
日期:2015-08-17 06:20:00程序设计版块每日发帖之星
日期:2016-07-16 06:20:00程序设计版块每日发帖之星
日期:2016-07-18 06:20:00每日论坛发贴之星
日期:2016-07-18 06:20:00黑曼巴
日期:2016-12-26 16:00:3215-16赛季CBA联赛之江苏
日期:2017-06-26 11:05:5615-16赛季CBA联赛之上海
日期:2017-07-21 18:12:5015-16赛季CBA联赛之青岛
日期:2017-09-04 17:32:0515-16赛季CBA联赛之吉林
日期:2018-03-26 10:02:16程序设计版块每日发帖之星
日期:2016-07-15 06:20:0015-16赛季CBA联赛之江苏
日期:2016-07-07 18:37:512015亚冠之萨济拖拉机
日期:2015-08-17 12:21:08
29 [报告]
发表于 2015-07-20 17:17 |只看该作者
22#楼, ip_summed在local_in被修改为checksum_none了,那修改之前是多少?

理论上,在driver层面,checksum行为应该不区分是否为本地报文,
那么,可以判断,楼主设备的driver具备硬件校验l4的能力,并且在rx阶段把skb->summed置为unnecessary。

1)如果是转发报文,那么在tx阶段,unnecessary=none,表示不需要硬件提供checksum offload,由软件保证l4校验和正确。
a. 如果不对报文做任何修改,那么由于收上来的checksum正确,自然发出去的是正确的;
b. 如果对报文内容进行了修改,并且不修改checksum,由于硬件不会干预,所以发出去的是错误的;
c. 楼主后来人为更正了校验和,并且没有修改unnecessary,这就回到了a,也能正确发送;
d. 按照local_in的方法,ip_summed设为none,理论上应该跟c的效果一样,但是实际情况不是这样,不知道该怎么解释。-_-。sorry!(收发网卡都是一样的么?)

2)对于local_in的行为,由于summed设置为none,由本地协议栈进行重新校验。其实这时候csum是多少无所谓,因为tcp_v4_rcv/tcp_v4_checksum_init里会覆盖这个值。

PS,楼主貌似在10提到过修改prerouting是没有问题的,请问那也是forward场景吗?

PS2,至于forward不修改后续seq/ack也没有问题,会不会是因为HTTP1.1的原因?瞎猜的,不知道实际server收到一个比预期大的ACK会怎么反应?

论坛徽章:
2
2015年亚洲杯之日本
日期:2015-03-25 11:21:322015亚冠之柏太阳神
日期:2015-07-13 10:36:04
30 [报告]
发表于 2015-07-20 18:44 |只看该作者
回复 29# nswcfd
  1. d. 按照local_in的方法,ip_summed设为none,理论上应该跟c的效果一样,但是实际情况不是这样,不知道该怎么解释。-_-。sorry!(收发网卡都是一样的么?)
复制代码
是的,收发在同一网卡中。
  1. PS,楼主貌似在10提到过修改prerouting是没有问题的,请问那也是forward场景吗?
复制代码
这个当时也是在 local_in 中
  1. PS2,至于forward不修改后续seq/ack也没有问题,会不会是因为HTTP1.1的原因?瞎猜的,不知道实际server收到一个比预期大的ACK会怎么反应?
复制代码
a. HTTP 1.1 ,不清楚啊,如果是这样的话,local_in 是不是应该也可以不修改 seq 和 ack,实际情况中,local_in 不修改不行,后续接收出错,并重发报文。

b. server 收到大 ACK,应该会丢掉


感谢 nswcfd 回答
   
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP