【随笔记】linux usb gadget ncm wrong ndp sign 问题修复
一、模拟网卡简介
在 Linux 通过 usb 模拟网卡时,有四种方式:
1. 使用 usb gadget rndis
2. 使用 usb gadget ecm
3. 使用 usb gadget ncm
4. 使用 usb gadget eem
rndis:是微软公司制定的协议规范, 不过似乎规范不完整, 引起 rndis host 驱动作者的强烈反对。lichee\linux-4.9\drivers\net\usb\rndis_host.c
ecm:传输的是纯粹的以太网包,一次USB传输只包含一个以太网帧,因此吞吐量较低,实测在 6MB/s 左右,Windows 的驱动不太好找,Ubuntu 可以直接支持。
ncm:ecm 的改进版本,每个NCM报文可以包含多个以太网帧,这种特性称为报文聚合,即调用一次URB可以发送或者接收多个IP报文,实测在 17MB/s 左右,Windows 自带有驱动(本文在 Win10 平台实测通过),Ubuntu 可以直接支持。
eem:了解不多。
二、问题现象
接入 Windows 之后,启用该网卡,会不停的输出 "Wrong NDP SIGN",并且无法相互 ping 通。
检查发现因为 ncm->ndp_sign 的值等于 0,未被正确赋值。(f_ncm.c)
分析发现 ncm->ndp_sign 只有在设置 CRC 模式的时候才会拷贝 ncm->parser_opts,由此可见 Win10 的 ncm 驱动并未主动配置 CRC 模式引起。
经调试发现 USB_CDC_SET_NTB_FORMAT 会被触发,会设置 ncm->parser_opts,那么如果也顺道一同拷贝 ncm->ndp_sign 应该就能解决问题。
实测确实解决了问题,既然 f_ncm.c 驱动有缺陷,那么很有可能最新的内核已经解决了此问题,查看了最新内核的驱动(v5.18),发现已经调整了 ncm->ndp_sign 顺序,在 switch 语句后面进行赋值,同样也能解决问题。
三、修复补丁
由于 5.9.y 相对于 4.9 版本改动较大,这里发出一个针对 4.9 版本修复此问题的最小改动补丁。
diff --git a/lichee/linux-4.9/drivers/usb/gadget/function/f_ncm.c b/lichee/linux-4.9/drivers/usb/gadget/function/f_ncm.c
old mode 100644
new mode 100755
index 639603722..278580b5a
--- a/lichee/linux-4.9/drivers/usb/gadget/function/f_ncm.c
+++ b/lichee/linux-4.9/drivers/usb/gadget/function/f_ncm.c
@@ -828,7 +828,7 @@ static int ncm_setup(struct usb_function *f, const struct usb_ctrlrequest *ctrl)
default:
goto invalid;
}
- ncm->ndp_sign = ncm->parser_opts->ndp_sign | ndp_hdr_crc;
+ // ncm->ndp_sign = ncm->parser_opts->ndp_sign | ndp_hdr_crc;
value = 0;
break;
}
@@ -846,6 +846,9 @@ static int ncm_setup(struct usb_function *f, const struct usb_ctrlrequest *ctrl)
w_value, w_index, w_length);
}
+ // lmx: fix ncm_unwrap_ntb() --> ncm->ndp_sign to==0, generate "Wrong NDP SIGN" Bug
+ ncm->ndp_sign = ncm->parser_opts->ndp_sign | (ncm->is_crc ? NCM_NDP_HDR_CRC : 0);
+
/* respond with data transfer or status phase? */
if (value >= 0) {
DBG(cdev, "ncm req%02x.%02x v%04x i%04x l%d\n",
实测吞吐量:
最新文章
- C#索引器
- 短信接口API
- Tomcat catalina.out日志使用log4j按天分割
- CloudStack系统部署系列教程-KVM
- bzoj3991: [SDOI2015]寻宝游戏--DFS序+LCA+set动态维护
- android之电话拨号器
- 【转】Android中如何使用Bundle传递对象[使用Serializable或者Parcelable] -- 不错
- BZOJ 1066: [SCOI2007]蜥蜴( 最大流 )
- cocos2d-html5
- 【实验室笔记】zedgraph控件属性总结
- 基于laravel5.5和vue2开发的个人博客
- L1-Day14
- <;二>;ELK-6.5.3学习笔记–使用rsyslog传输管理nginx日志
- sublime text下安装插件autoprefixer
- Java微信二次开发(十)
- Mysql主从同步问题汇总
- Oracle EBS 查看双节点是否做了信任
- C# 获取文件名、目录、后缀、无后缀文件名、扩展名、根目录等
- /etc/ssh/sshd_config 配置(ssh连接)
- Java 之单例设计模式