eth0转wlan0转发TCP异常及修复后速率过低问题求助
已完成eth0到wlan0的NAT转发配置,ICMP(ping)流量正常,但TCP流量(curl、iperf)异常。抓包发现wlan0侧发送的TCP包缺失14字节以太网帧头,手动修改wlan驱动发送函数中TCP场景的skb->len增加14字节后,TCP功能恢复但出现严重性能问题(速率降为直接使用wlan0的1/4,伴随大量重传丢包)。已排除EMAC驱动问题(转发至rmnet_data正常),以下是新的排查方向:
检查skb的**数据偏移(skb->data_offset)**与头部标记:
对比转发场景下eth0接收的skb和直接从wlan0发起的skb,查看skb->data_offset、skb->mac_header、skb->network_header字段。转发的skb可能保留了eth0的以太网帧头在skb->head区域,但skb->data指向IP层,此时若wlan驱动仅以skb->len作为发送长度,会漏掉前面的14字节帧头。确认驱动是否正确识别skb的mac_header偏移,是否需要手动调整len以包含帧头部分。排查NAT/iptables对skb结构的修改:
对比TCP流量在NAT处理前后的skb关键字段(skb->len、skb->data、skb->tail、skb->end)。SNAT/DNAT操作可能涉及skb重组、头部修改,若操作后未正确更新skb->len或调整数据指针,会导致驱动发送时长度错误。可以临时禁用NAT规则,测试TCP流量是否正常(此时需确保路由可达),缩小问题范围。分析wlan驱动对转发skb的处理逻辑:
直接从wlan0发起的skb由协议栈构造,而转发的skb来自其他网口,两者的skb结构可能存在差异(如是否携带硬件帧头、是否为线性skb)。检查wlan驱动发送函数中,是否对不同来源的skb做了差异化处理?比如是否默认认为skb已包含wlan帧头,而转发的skb还带着eth0的以太网帧头,导致驱动错误截断?另外,手动加14字节后性能下降,可能是驱动重复添加了帧头,或者skb内存布局混乱引发传输校验错误,需对比修改前后的wlan侧抓包,看是否存在帧头重复或数据错误。验证TCP与ICMP的skb处理差异:
为何ICMP流量正常?对比TCP和ICMP转发时的skb状态:ICMP包通常更小,无需分片,NAT处理更简单;而TCP包可能涉及MSS调整、分片重组,协议栈或驱动在处理时可能遗漏了长度更新。检查是否TCP流量在转发过程中触发了特定的skb修改逻辑(如skb_trim、skb_push),导致skb->len被错误修改。检查skb的线性/非线性状态:
转发的skb可能是非线性的(skb_shinfo(skb)->nr_frags > 0),若wlan驱动的发送函数未正确处理分片数据,仅修改线性部分的skb->len会导致实际发送的数据不完整,引发重传。打印skb->len、skb->data_len、skb->truesize等字段,确认skb的总数据长度是否正确,驱动是否完整发送了所有分片数据。排查流量控制(tc)规则的影响:
查看eth0和wlan0上是否存在tc规则:tc qdisc show dev eth0 tc qdisc show dev wlan0 tc filter show dev eth0 tc filter show dev wlan0若存在流量整形、裁剪类规则,可能会修改skb的长度或结构,导致TCP流量异常。临时禁用所有tc规则后测试,确认是否是tc导致的问题。
内容的提问来源于stack exchange,提问作者smiljanic997

