一、模拟网卡简介

在 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 语句后面进行赋值,同样也能解决问题。

f_ncm.c « function « gadget « usb « drivers - kernel/git/torvalds/linux.git - Linux kernel source tree

三、修复补丁

由于 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",

实测吞吐量:

【随笔记】linux usb gadget ncm wrong ndp sign 问题修复的更多相关文章

  1. Linux usb gadget框架概述

    很幸运,在公司开发了gadget相关驱动,总结下来,大大小小开发了四个与gadget相关的驱动,字符驱动.g_multi.g_ether.g_zero,在这里把自己对gadget的开发中自己的感悟记录 ...

  2. Android USB gadget configfs学习笔记总结

    1.一个config_item 是通过显式用户空间mkdir操作创建的,通过rmdir销毁.属性(文件)在mkdir之后出现,可以通过read和write读取或修改属性文件.与sysfs一样,read ...

  3. Linux USB ECM Gadget 驱动介绍

    ​1 USB ECM介绍 USB ECM,属于USB-IF定义的CDC(Communication Device Class)下的一个子类:Ethernet Networking Control Mo ...

  4. Android USB gadget框架学习笔记

    一 Gadget框架结构 kernel/drivers/usb/gadget,这个目录是android下usbgadget的主要目录. Gadget功能组织单元:主要文件android.c,usb g ...

  5. linux USB 编程

    Linux USB架构 可以看出一个USB体系需要4个驱动:USB设备驱动(主要编写这部分),USB主控制器驱动,Gadget驱动,UDC驱动. USB主要有4个功能: MassStorage:大容量 ...

  6. Linux USB Project

    转自:http://www.linux-usb.org/ Welcome to the home of the Linux USB Project This web site was created ...

  7. Linux USB驱动

    linux usb 驱动详解 一 http://blog.163.com/cl2006ky@126/blog/static/87195173201131245557340/ USB设备驱动开发-USB ...

  8. Linux usb子系统(二):USB设备驱动usb-skeleton.c

    usb驱动分为通过usbfs操作设备的用户空间驱动,内核空间的内核驱动.两者不能同时进行,否则容易引发对共享资源访问的问题,死锁!使用了内核驱动,就不能在usbfs里驱动该设备. 下面转载的一篇分析u ...

  9. Linux usb子系统(一) _写一个usb鼠标驱动

    USB总线是一种典型的热插拔的总线标准,由于其优异的性能几乎成为了当下大小设备中的标配. USB的驱动可以分为3类:SoC的USB控制器的驱动,主机端USB设备的驱动,设备上的USB Gadget驱动 ...

  10. USB gadget 驱动 printer.c 分析

    1. modprobe g_printer idVendor=0x0525 idProduct=0xa4a8 modprobe后面也可以加模块参数 2. prn_example从stdout获取数据然 ...

随机推荐

  1. ES6 学习笔记(一)let、const与作用域

    一.let命令 1.1用法 1.1.1 let类似于var,但所声明的变量只在let命令所在的代码块有效. 如: { let a = 10 var b = 20 } console.log(b) co ...

  2. 京东云开发者|经典同态加密算法Paillier解读 - 原理、实现和应用

    摘要 随着云计算和人工智能的兴起,如何安全有效地利用数据,对持有大量数字资产的企业来说至关重要.同态加密,是解决云计算和分布式机器学习中数据安全问题的关键技术,也是隐私计算中,横跨多方安全计算,联邦学 ...

  3. Java自定义排序:继承Comparable接口,重写compareTo方法(排序规则)

    代码: 1 import java.util.*; 2 3 /** 4 * 学习自定义排序:继承Comparable接口,重写compareTo方法(排序规则). 5 * TreeMap容器的Key是 ...

  4. CC3

    cc_link_three 0x00前言 这里要单独学cc链子三是因为它的调用方式不是执行命令而是代码执行,是一种动态类加载机制来执行代码,然后类加载的时候要用类加载器 0x01开整 首先明白调用机制 ...

  5. 【lwip】12-一文解决TCP原理

    目录 前言 12.1 TCP协议简介 12.2 TCP相关的一些概念词 12.2.1 MSL 12.2.2 MSS 12.3 TCP工作特性 12.3.1 面向连接 12.3.2 全双工通信 12.3 ...

  6. SpringBoot yml配置文件中,logging.level报错

    报错 *************************** APPLICATION FAILED TO START *************************** Description: ...

  7. 关于mysql远程连接失败的问题解决

    解决办法 mysql 数据库user表配置密码 mysql 数据库user表配置plugin字段为mysql_native_password mysql 数据库user表host字段更改为% mysq ...

  8. Kubernetes(K8S) 配置管理-ConfigMap 介绍

    作用:存储不加密数据到 etcd,让 Pod 以变量或者 Volume 挂载到容器中 场景:配置文件 创建配置文件 redis.properties redis.host=127.0.0.1 redi ...

  9. 【Java SE】课程目录

    〇.课程简介 一.前言入门 二.数据类型.运算符.方法 三.流程控制 四.Idea.方法 五.数组 六.类.对象.封装.构造 七.Scanner类.Random类.ArrayList类 八.Strin ...

  10. ORM执行sql语句 双下划线 外键字段创建 ORM跨表查询

    目录 模型层之ORM执行SQL语句 方式1一 方式二 方式三 神奇的双下划线查询 ORM外键字段的创建 1.创建基础表 2.确定外键关系 3.表的查看 数据的录入 外键字段相关操作 针对一对多 ''' ...