USB/IP 协议、PDU 与公共核心

USB/IP 协议、PDU 与公共核心

1. 两层协议

用户态管理协议负责DEVLIST和IMPORT,定义在tools/usb/usbip/src/usbip_network.h。导入完成后,socket交给内核,使用usbip_common.h中的URB协议。

默认服务端端口为TCP 3240。用户态在连接后设置TCP_NODELAY,降低小控制传输的Nagle延迟。

2. 四类内核命令

命令 方向 语义
CMD_SUBMIT 1 VHCI→Stub/VUDC 提交URB
CMD_UNLINK 2 VHCI→Stub/VUDC 取消指定seqnum
RET_SUBMIT 3 Stub/VUDC→VHCI URB完成
RET_UNLINK 4 Stub/VUDC→VHCI 取消结果

数据面usbip_header固定48字节:20字节basic header加28字节最大union。基本头包含commandseqnumdeviddirectionepseqnum标识请求;Stub使用(busnum << 16) | devnum形成devid。

3. SUBMIT字段

usbip_header_cmd_submit序列化:

  • 可跨网络表达的URB transfer flags;
  • transfer buffer length;
  • start frame;
  • ISO packet数量;
  • interval;
  • 8字节control setup packet。

并非所有本地URB flag都可直接传输,tweak_transfer_flags()会过滤DMA映射等仅本机有效的标志。

RET_SUBMIT返回status、actual length、frame、ISO packet数和error count。

4. Payload顺序

1
2
3
4
5
CMD_SUBMIT OUT:
header -> OUT data -> ISO descriptors

RET_SUBMIT IN:
header -> IN data -> ISO descriptors

非ISO传输可使用线性buffer或scatter-gather。公共层的usbip_recv_xbuff()和发送侧kvec/iov_iter负责数据搬运。

ISO descriptor包含offset、期望length、actual length和status。Stub限制单URB最多1024个ISO packets,并检查负数、越界及长度;VUDC还按endpoint max packet验证packet数。

5. 字节序

usbip_header_correct_endian()对全部32-bit头字段执行CPU与big-endian转换,ISO descriptor同样按网络序处理。Setup packet本身是USB Chapter 9格式,不作为五个普通32-bit字段转换。

解包顺序必须是:

  1. 完整接收固定头;
  2. 转为CPU字节序;
  3. 验证command和长度;
  4. 分配URB/buffer;
  5. 接收payload和ISO描述符。

远端给出的有符号长度和packet数量不能在验证前转换为分配大小。

6. usbip_common.c

关键函数:

  • usbip_pack_pdu():URB和command-specific header互转;
  • usbip_header_correct_endian():网络字节序;
  • usbip_recv():循环接收指定长度,处理EOF和signal;
  • usbip_alloc_iso_desc_pdu():创建ISO descriptor PDU;
  • usbip_recv_iso():接收并验证ISO结果;
  • usbip_recv_xbuff():接收IN/OUT payload;
  • usbip_pad_iso():整理非连续ISO IN数据;
  • dump/debug函数:输出header和URB字段。

usbip_debug_flag是可写模块参数,同时通过各设备的usbip_debug sysfs暴露位掩码。

7. Event Handler

公共层创建名为usbip_event的单线程workqueue。每个usbip_device以位图记录:

  • SHUTDOWN:先关闭socket/线程;
  • RESET:恢复到可重连状态;
  • UNUSABLE:永久标记不可用;
  • BYE:对象即将移除。

usbip_event_add()使用全局spinlock把设备去重后加入event list。worker持有该设备sysfs_lock,严格按shutdown→reset→unusable顺序调用前端回调,并唤醒usbip_stop_eh()等待者。

这是全局串行恢复路径:一个设备的慢shutdown会延迟其它USB/IP连接的event处理。

8. 协议边界

内核URB协议没有独立session认证、MAC、加密、重放保护或每PDU长度字段。消息边界依赖command对应的固定头及其中长度。TCP只保证有序字节流,不保证对端可信。

文章互动

阅读 --

留言

0 条留言

正在加载留言…