当前位置: 首页 > news >正文

LWIP协议栈实现ARP协议

1) 核心数据结构与状态机(对应图片:etharp_entry 与 etharp_q_entry)

  • 代码:struct etharp_entry
    • 字段说明:
      • q:挂载的等待发送的 pbuf(或队列,取决于 ARP_QUEUEING)
      • ipaddr / ethaddr / netif:映射关系与所属接口
      • ctime:条目年龄(以秒计;由 etharp_tmr 每秒自增)
      • state:ETHARP_STATE_(EMPTY、PENDING、STABLE、REREQUESTING_、STATIC)
  • 行为:
    • PENDING:已发送 ARP 请求,等待应答。可以挂载 1 个或多个待发包(取决 ARP_QUEUEING)。
    • STABLE:已解析到 MAC,可直接发送;ctime 达到 ARP_MAXAGE 则过期。
      在这里插入图片描述在这里插入图片描述
      上图是arp_entry结构体和etharp_q_entry结构体。
      在这里插入图片描述
      下图是每个arp结构的state状态机。在这里插入图片描述

2) 条目查找与回收策略(对应代码:etharp_find_entry)

  • 功能:一次扫描实现查找/选择回收项/创建新项的逻辑(提高效率,避免多遍扫描)。
  • 回收优先级(若无空槽并且允许回收 ETHARP_FLAG_TRY_HARD):
    1. 最久的 stable(不含 static)
    2. 最久的 pending(无队列)
    3. 最久的 pending(有队列)
  • 图片提示: ARP_QUEUEING 宏和默认值(通常关闭),说明队列功能默认不开启以节省内存与复杂度。
  • 修改建议:若设备需要短时间内缓存多个待发包(例如启动爆发流量),开启 ARP_QUEUEING 并适当设置 ARP_QUEUE_LEN;但要增加 MEMP_ARP_QUEUE 池。

在这里插入图片描述

3) 更新缓存(对应代码:etharp_update_arp_entry,etharp_input)

  • etharp_input 收到 ARP 包(request/reply)时:
    • 先通过 etharp_update_arp_entry 更新/插入缓存(若为请求且目标为本机,会触发 reply)。
    • 对于 reply:只是更新条目(并会把挂起队列的数据发出)。
  • 若条目由 PENDING -> STABLE:会弹出队列,调用 ethernet_output 发送并 pbuf_free。
  • 图片(Wireshark trace)说明:当内核重试 TCP 但 ARP 未解析时会出现大量重传;抓包显示 ARP 请求/应答后 TCP 连接恢复,说明 ARP 解析是许多上层超时/重传的根源。
  • 在这里插入图片描述

4) 发包路径与决策(对应代码:etharp_output / etharp_query / etharp_output_to_arp_index)

  • 发送单播 IP 包:

    • 先检查广播/多播,直接选择目标 MAC。
    • 否则在 ARP 表查找稳定条目(快速 path);若找到,直接 etharp_output_to_arp_index -> ethernet_output。
    • 若没找到,调用 etharp_query:创建/标记 pending、发送 ARP request,并把 pbuf 挂到表项(或复制/引用,见下)。
  • 关于 pbuf 挂载策略(关键点):

    • 如果 q 的 pbuf 类型会被上层修改(PBUF_NEEDS_COPY),则必须复制为 PBUF_RAM(pbuf_clone),保证队列中的数据不被上层改写。
    • 默认行为(无队列)会只保存一份 pbuf(覆盖旧的)。
  • 在这里插入图片描述

5) 请求/重发/老化策略(对应代码常量与 etharp_tmr)

  • ARP_MAXPENDING(默认 5 秒)控制 pending 条目失效时间。若未收到回复,ethtarp_tmr 会在到期后释放条目。
  • ARP_MAXAGE(默认通常 5 分钟),在接近过期时会做 re-request:
    • ARP_AGE_REREQUEST_USED_UNICAST = ARP_MAXAGE - 30(15/30s 的差异用于广播/单播策略,见源码)
  • etharp_tmr 实现:每秒自增 ctime,达到阈值会 etharp_request(对于 pending)或 etharp_free_entry(过期)。
    在这里插入图片描述

在这里插入图片描述

6) ARP 请求构造与发送(etharp_request / etharp_raw)

  • etharp_raw 负责构造 ARP 报文(填 arp header、sender/target 地址)并调用 ethernet_output 发送(PBUF_LINK + PBUF_RAM)。
  • 如果使用 AUTOIP(link-local),对特殊源 IP 必须用广播发送(RFC 要求)。
  • 图片(ARP 帧格式图)对照:头部字段顺序、各字段长度(hw type、proto type、hwlen、protolen、opcode、sender hw/ip、target hw/ip)。
    在这里插入图片描述

7) queue 与内存(ARP 队列与 pbuf 类型)

  • 如果挂载队列,必须考虑内存池(MEMP_ARP_QUEUE)与 pbuf 池(PBUF_RAM 当需要复制时)。
  • PBUF_NEEDS_COPY 宏会检测 pbuf 类型是否安全入队(PBUF_REF/PBUF_ROM 等不可直接入队)。
  • 若内存不足(无法为队列分配 memp 或无法复制 pbuf),会丢弃并返回 ERR_MEM,并统计 ETHARP memerr(见代码调用 ETHARP_STATS_INC)。

8) 性能与问题排查建议

  • 常见问题:ARP 导致上层 TCP 超时/重传(见 Wireshark),最终原因往往是:
    • ARP 请求未发出(驱动问题 / ethernet_output 未调用)
    • ARP 请求发送但未到达对端(VLAN/交换机/子网配置错误)
    • 驱动或 DMA 未把 RX 帧传递给 lwIP(ethernetif_input 未上送 pbuf)
    • ARP 表条目被过快回收(ARP_MAXAGE 设置过小)
  • 排查清单:
    • 抓包看是否存在 ARP 请求/应答(Wireshark)。若有应答但内核仍在重传,说明内核未把应答更新到表(检查 etharp_input 是否被调用及 netif 关联)。
    • 开启 LWIP_DEBUG/ETHARP_DEBUG 与统计(etharp.xmit / eth arp.recv / eth arp.memerr)观察。
    • 检查 MEMP_ARP_QUEUE 与 PBUF_POOL 是否不足(pbuf_alloc 失败会导致丢包)。
  • 优化建议:
    • 在高并发或 burst 场景启用 ARP_QUEUEING 与合理 ARP_QUEUE_LEN,并增大 MEMP_ARP_QUEUE 数量。
    • 若系统多接口 / 路由复杂,配置 ETHARP_TABLE_MATCH_NETIF 与 LWIP_HOOK_ETHARP_GET_GW 来控制回路与网关选择。
    • 对延迟敏感的应用可以适度增大 ARP_MAXAGE,或对关键目标预填 ARP(etharp_add_static_entry)。
      正常arp表如下。
      在这里插入图片描述
http://www.dtcms.com/a/339788.html

相关文章:

  • 如何看出有没有做raid,并做的是raid几
  • 仲裁器设计(三)-- Weighted Round Robin 权重轮询调度
  • 信号以及共享内存
  • 设计模式笔记_行为型_命令模式
  • Pygame中,精灵Sprite与精灵组Group,显性入组与隐性入组,它们之间的关系是什么?
  • JB4-8-事务机制
  • 决策树学习总结
  • 在 IntelliJ IDEA 中修改 Git Commit 描述
  • Java秋招:高并发查询优化
  • 【学习】Linux 内核中的 cgroup freezer 子系统
  • 基于SpringBoot的高校心理教育辅导系统
  • 【python实用小脚本-190】Python一键删除PDF任意页:输入页码秒出干净文件——再也不用在线裁剪排队
  • Android Cordova 开发 - Cordova 嵌入 Android
  • 如何免费给视频加字幕
  • 【论文阅读】SIMBA: single-cell embedding along with features(1)
  • 当qtcpserver类对象释放时,该类下面的多个qtcpsocket连接会释放吗
  • 论文阅读系列(一)Qwen-Image Technical Report
  • IATF 16949认证是什么?
  • GaussianLSS
  • Java 并发同步工具类详解
  • WordPress 从删除文章后(清空回收站)保存被删除文章的链接到txt
  • 24.早期目标检测
  • Nacos-7--扩展一下:0-RTT和1-RTT怎么理解?
  • 【unitrix数间混合计算】3.2 非零标记trait(non_zero.rs)
  • JVM垃圾回收(GC)深度解析:原理、调优与问题排查
  • libvaapi,libva-utils源码获取并编译测试
  • 深入理解AQS:并发编程的基石
  • django生成迁移文件,执行生成到数据库
  • sfc_os!SfcValidateDLL函数分析之SfcGetValidationData
  • Android音频学习(十三)——音量配置文件分析